#include "ParamManager.h" #include "WriteLog.h" #include "DBFHashList2.h" #include #include #include #include #include #include #include "CommonFunc.h" #include #include #include #include #include #include #include "QSettings2.h" #include "transfer.h" #ifdef PARAMMANAGER_LANE #include "CCommonEvent.h" #include "LaneApp.h" #endif CParamMan::CParamMan() { } CParamMan::~CParamMan() { //qDebug()<<"CParamMan::~CParamMan Enter"; CloseParam(); //qDebug()<<"CParamMan::~CParamMan Leave"; } int CParamMan::GetIndex(const int PFileId, const int roadNo, const int staNo) { for(int i=0;ishowMessage("加载(" + QString::number(i+1) + "/" + QString::number(m_PFileInfo.size()) + ")" + m_PFileInfo[i].PFileCName + "...", Qt::AlignBottom, Qt::blue); #endif if(!LoadParam(m_PFileInfo[i])) { return false; } } WRITE_LOG("[加载参数文件]参数文件加载完成"); return true; } void CParamMan::CloseParam() { QMutexLocker lock(&m_Mutex); for(int i=0;iOpen(tbName)) { WRITE_LOG("打开DBF表失败,TableName=%s", tbName.toUtf8().data()); return false; } //RecordCount = PFileInfo.pDBF->GetRecordCount(); return true; } bool CParamMan::UnLoadDBF(CPFileInfo &PFileInfo) { if(PFileInfo.pDBF != nullptr) { PFileInfo.pDBF->Close(); delete PFileInfo.pDBF; PFileInfo.pDBF = nullptr; return true; } return false; } bool CParamMan::LoadHash(CPFileInfo &PFileInfo, QString &LoadFileName) { //UnLoadHash(PFileInfo); PFileInfo.hHash = HASH_CreateList(); QString BasePath = m_LibBasePath; QSettings2 ini(BasePath + QString("DBFHASHLIST.INI"), QString("GBK"), false); LoadFileName = ini.value(QString("DBFHASHLIST/BLACK_%1").arg(PFileInfo.PFileId), PFileInfo.PFileName); QString tbName = BasePath + LoadFileName; if(HASH_LoadList(PFileInfo.hHash, PFileInfo.PFileId, tbName, PFileInfo.HashKeyFieldName, PFileInfo.VersionFieldName) < 0) { WRITE_LOG("打开Hash表失败,TableName=%s", tbName.toUtf8().data()); return false; } //RecordCount = HASH_GetRecordCount(PFileInfo.hHash); return true; } bool CParamMan::UnLoadHash(CPFileInfo &PFileInfo) { //Hash表参数没有卸载功能,执行后台加载切换会自动卸载前一版本 if(PFileInfo.hHash != 0) { HASH_DestroyList(PFileInfo.hHash); PFileInfo.hHash = 0; return true; } return false; } #ifdef PARAMMANAGER_LANE bool CParamMan::LoadFee(CPFileInfo &PFileInfo) { PFileInfo.pLib = new QLibrary("libFee"); if(PFileInfo.pLib->load()) { getPath = (FUNC_getPath)PFileInfo.pLib->resolve("getPath"); if(!getPath) { WRITE_LOG("加载动态库失败(getPath)"); return false; } init = (FUNC_init)PFileInfo.pLib->resolve("init"); if(!init) { WRITE_LOG("加载动态库失败(init)"); return false; } deInit = (FUNC_deInit)PFileInfo.pLib->resolve("deInit"); if(!deInit) { WRITE_LOG("加载动态库失败(deInit)"); return false; } getLibVersion = (FUNC_getLibVersion)PFileInfo.pLib->resolve("getLibVersion"); if(!getLibVersion) { WRITE_LOG("加载动态库失败(getLibVersion)"); return false; } getFeeDataVersion = (FUNC_getFeeDataVersion)PFileInfo.pLib->resolve("getFeeDataVersion"); if(!getFeeDataVersion) { WRITE_LOG("加载动态库失败(getFeeDataVersion)"); return false; } getFee = (FUNC_getFee)PFileInfo.pLib->resolve("getFee"); if(!getFee) { WRITE_LOG("加载动态库失败(getFee)"); return false; } getStaFee = (FUNC_getStaFee)PFileInfo.pLib->resolve("getStaFee"); if(!getStaFee) { WRITE_LOG("加载动态库失败(getStaFee)"); return false; } if(init("1", m_LibBasePath.toUtf8().data()) != 0) { WRITE_LOG("初始化失败-init"); return false; } return true; }else{ WRITE_LOG("加载动态库失败:%s", PFileInfo.pLib->errorString().toUtf8().data()); return false; } } bool CParamMan::UnLoadFee(CPFileInfo &PFileInfo) { if(PFileInfo.pLib != nullptr) { if(PFileInfo.pLib->isLoaded()) { #ifndef QT_DEBUG deInit(); #endif PFileInfo.pLib->unload(); } delete PFileInfo.pLib; PFileInfo.pLib = nullptr; return true; } return false; } #endif bool CParamMan::LoadSQB(CPFileInfo &PFileInfo) { //SQLITE 打开和关闭一定要小心 bool bOpen = false; QString DBName = QString("DB_%1_%2_%3_%4").arg(PFileInfo.PFileCode).arg(PFileInfo.PFileId).arg(PFileInfo.RoadNo).arg(PFileInfo.StaNo); { QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", DBName); QString dbFileName = m_LibBasePath + PFileInfo.PFileName; db.setDatabaseName(dbFileName); if(!db.open()){ QSqlError e = db.lastError(); WRITE_LOG("打开数据库(%s)失败,ErrorInfo=%s", dbFileName.toUtf8().data(), e.text().toUtf8().data()); bOpen = false; }else{ //RecordCount = GetRecordCount(PFileInfo.PFileId); PFileInfo.pQrySQLite = new QSqlQuery(db); bOpen = true; } } if(!bOpen) { QSqlDatabase::removeDatabase(DBName); } return bOpen; } bool CParamMan::UnLoadSQB(CPFileInfo &PFileInfo) { //SQLITE 打开和关闭一定要小心 if(PFileInfo.pQrySQLite != nullptr) { QString DBName = QString("DB_%1_%2_%3_%4").arg(PFileInfo.PFileCode).arg(PFileInfo.PFileId).arg(PFileInfo.RoadNo).arg(PFileInfo.StaNo); PFileInfo.pQrySQLite->clear(); PFileInfo.pQrySQLite->finish(); delete PFileInfo.pQrySQLite; PFileInfo.pQrySQLite = nullptr; { QSqlDatabase db = QSqlDatabase::database(DBName); db.close(); } QSqlDatabase::removeDatabase(DBName); return true; } return false; } bool CParamMan::LoadIni(CPFileInfo &PFileInfo) { PFileInfo.pIniList = new QStringList(); QSettings ini(m_LibBasePath + QString("HIGHWAY.INI"), QSettings::IniFormat); ini.beginGroup(QString("FUNCTION")); QStringList iniList = ini.allKeys(); foreach (QString key,iniList) { PFileInfo.pIniList->append(key + "=" + ini.value(key, "0").toString()); } ini.endGroup(); return true; } bool CParamMan::UnLoadIni(CPFileInfo &PFileInfo) { if(PFileInfo.pIniList != nullptr) { PFileInfo.pIniList->clear(); delete PFileInfo.pIniList; PFileInfo.pIniList = nullptr; return true; } return false; } QString CParamMan::GetVersion(int PFileId, int InfoType) { QMutexLocker lock(&m_Mutex); return GetBaseInfo(PFileId, m_LocalRoadNo, m_LocalStaNo, InfoType); } QDateTime CParamMan::GetGenTime(int pFileId) { QMutexLocker lock(&m_Mutex); int index = GetIndex(pFileId, m_LocalRoadNo, m_LocalStaNo); if(index >= 0) { return QDateTime::fromMSecsSinceEpoch(m_PFileInfo[index].PFileGenTime); } return QDateTime::fromMSecsSinceEpoch(0); } //InfoType=1获取版本号,InfoType=2获取启用日期 QString CParamMan::GetBaseInfo(const int PFileId, const int roadNo, const int staNo, const int InfoType) { //QMutexLocker lock(&m_Mutex); QString BaseInfo("0"); QString FieldName(""); int index = GetIndex(PFileId, roadNo, staNo); if(index >= 0) { if(InfoType== 1) { FieldName = m_PFileInfo[index].VersionFieldName; }else{ FieldName = m_PFileInfo[index].StartDateFieldName; } if(!FieldName.isEmpty()) { switch(m_PFileInfo[index].LoadType) { case PFILE_LOADTYPE_DBF: if(m_PFileInfo[index].pDBF != nullptr && m_PFileInfo[index].pDBF->GetRecordCount() > 0) { QString VerInfo = ""; m_PFileInfo[index].pDBF->First(); if(m_PFileInfo[index].pDBF->dbf_get(FieldName, VerInfo) >= 0) { BaseInfo = VerInfo; }else{ WRITE_LOG("获取版本信息失败:%s", m_PFileInfo[index].PFileName.toUtf8().data()); } } break; #ifdef PARAMMANAGER_LANE case PFILE_LOADTYPE_FEE: if(m_PFileInfo[index].pLib != nullptr && m_PFileInfo[index].pLib->isLoaded()) { char versionAry[64] ={0}; char dataVersionAry[64] = {0}; int retValue = getLibVersion(versionAry, sizeof(versionAry), dataVersionAry, sizeof(dataVersionAry)); if(retValue == 0) { if(InfoType == 2) { BaseInfo = QString::fromUtf8(versionAry); }else{ BaseInfo = QString::fromUtf8(dataVersionAry); } }else{ WRITE_LOG("FileName=%s,RetValue=%d", m_PFileInfo[index].PFileName.toUtf8().data(), retValue); } } break; #endif case PFILE_LOADTYPE_HASH: if(m_PFileInfo[index].hHash != nullptr) { QString VerInfo = ""; if(HASH_GetVerInfo(m_PFileInfo[index].hHash, VerInfo) >= 0) { BaseInfo = VerInfo.mid(0, VerInfo.indexOf(':')); }else{ WRITE_LOG("获取版本信息失败:%s", m_PFileInfo[index].PFileName.toUtf8().data()); } }; break; case PFILE_LOADTYPE_INI: BaseInfo = "0"; break; case PFILE_LOADTYPE_SQB: if(m_PFileInfo[index].pQrySQLite != nullptr) { QString sql = "select " + FieldName + " from " + m_PFileInfo[index].HashKeyFieldName + " LIMIT 1"; if(m_PFileInfo[index].pQrySQLite->exec(sql) && m_PFileInfo[index].pQrySQLite->next()) { BaseInfo = m_PFileInfo[index].pQrySQLite->value(0).toString(); }else{ WRITE_LOG("获取版本信息失败:%s", m_PFileInfo[index].PFileName.toUtf8().data()); } } break; } } }else{ WRITE_LOG("PFileId错误,PFileId=%d", PFileId); } if(InfoType == 1) { //版本号去掉[空格\/-:.],这样可以使用启用日期作为版本号 return BaseInfo.remove(QRegExp("[\\s]|[-]|[:]|[/]|[.]|[\\\\]")); //return BaseInfo; }else{ //启用日期不做筛选 return BaseInfo; } } QString CParamMan::GetParamCName(int PFileId) { QMutexLocker lock(&m_Mutex); int index = GetIndex(PFileId, m_LocalRoadNo, m_LocalStaNo); if(index >= 0){ return m_PFileInfo[index].PFileCName; }else{ return QString("参数名称获取错误"); } } QString CParamMan::GetParamPFName(int PFileId) { QMutexLocker lock(&m_Mutex); int index = GetIndex(PFileId, m_LocalRoadNo, m_LocalStaNo); if(index >= 0){ return m_PFileInfo[index].PFileName; }else{ return QString("参数名称获取错误"); } } int CParamMan::GetRecordCount(const int PFileId, const int roadNo, const int staNo) { int RecordCount = -1; int index = GetIndex(PFileId, roadNo, staNo); if(index >= 0) { switch(m_PFileInfo[index].LoadType) { case PFILE_LOADTYPE_DBF: if(m_PFileInfo[index].pDBF != nullptr) { RecordCount = m_PFileInfo[index].pDBF->GetRecordCount(); }else{ WRITE_LOG("%s,获取记录数失败,pDBF==NULL", m_PFileInfo[index].PFileCName.toUtf8().data()); } break; case PFILE_LOADTYPE_FEE: RecordCount = 0; break; case PFILE_LOADTYPE_HASH: if(m_PFileInfo[index].hHash != 0) { RecordCount = HASH_GetRecordCount(m_PFileInfo[index].hHash); }else{ WRITE_LOG("%s获取记录数失败,hHash=0", m_PFileInfo[index].PFileCName.toUtf8().data()); } break; case PFILE_LOADTYPE_INI: if(m_PFileInfo[index].pIniList != nullptr) { RecordCount = m_PFileInfo[index].pIniList->count(); } break; case PFILE_LOADTYPE_SQB: if(m_PFileInfo[index].pQrySQLite != nullptr) { QString sql = "select count(*) from " + m_PFileInfo[index].HashKeyFieldName; if(m_PFileInfo[index].pQrySQLite->exec(sql) && m_PFileInfo[index].pQrySQLite->next()) { QVariant v = m_PFileInfo[index].pQrySQLite->value(0); RecordCount = v.toInt(); }else{ WRITE_LOG("%s获取记录数失败,SQL=%s", m_PFileInfo[index].PFileCName.toUtf8().data(), sql.toUtf8().data()); } } break; } }else{ WRITE_LOG("PFileId错误,PFileId=%d", PFileId); } return RecordCount; } int CParamMan::GetStaInfo(int RoadNo, int StaNo, int &SubAreaNo, QString &IGantryId, QString &IGantryHex, QString &OGantryId, QString &OGantryHex, QString &RoadName, QString &StationName) { SubAreaNo = 0; IGantryId = ""; IGantryHex = ""; OGantryId = ""; OGantryHex = ""; QMutexLocker lock(&m_Mutex); int index = GetIndex(PFILE_ID_STATION, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return -1001; } if((m_PFileInfo[index].pDBF == nullptr) || (m_PFileInfo[index].pDBF->IsOpened() == false)) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return -1002; } int FieldRoadNo = m_PFileInfo[index].pDBF->GetFieldIndex("RoadNo"); int FieldStaNo = m_PFileInfo[index].pDBF->GetFieldIndex("StaNo"); //int FieldSubAreaNo = m_PFileInfo[index].pDBF->getFieldIndex("SUBAREANO"); qint64 iRoadNo, iStaNo, iSubAreaNo; //QString StaName = ""; //QString RoadName = ""; //QString AllName = ""; for(int i=m_PFileInfo[index].pDBF->First();i>=0;i=m_PFileInfo[index].pDBF->Next()) { if(m_PFileInfo[index].pDBF->dbf_get(FieldRoadNo, iRoadNo) >=0 && m_PFileInfo[index].pDBF->dbf_get(FieldStaNo, iStaNo) >=0){ if(iRoadNo == RoadNo && iStaNo == StaNo){ m_PFileInfo[index].pDBF->dbf_get("SUBAREANO", iSubAreaNo); SubAreaNo = iSubAreaNo; m_PFileInfo[index].pDBF->dbf_get("IGANTRYID", IGantryId); m_PFileInfo[index].pDBF->dbf_get("IGANTRYHEX", IGantryHex); m_PFileInfo[index].pDBF->dbf_get("OGANTRYID", OGantryId); m_PFileInfo[index].pDBF->dbf_get("OGANTRYHEX", OGantryHex); m_PFileInfo[index].pDBF->dbf_get("ROADNAME", RoadName); m_PFileInfo[index].pDBF->dbf_get("STANAME", StationName); if(SubAreaNo == 0 || IGantryId == "" || IGantryHex == "" || OGantryId == "" || OGantryHex == "") { return -3; } return 0; } } }; return -1003; } QString CParamMan::GetStaName(int RoadNo, int StaNo, bool bIncludeRoadName) { QMutexLocker lock(&m_Mutex); int index = GetIndex(PFILE_ID_STATION, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return QString(""); } if((m_PFileInfo[index].pDBF == nullptr) || (m_PFileInfo[index].pDBF->IsOpened() == false)) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return QString(""); } int FieldRoadNo = m_PFileInfo[index].pDBF->GetFieldIndex("RoadNo"); int FieldStaNo = m_PFileInfo[index].pDBF->GetFieldIndex("StaNo"); qint64 iRoadNo, iStaNo; QString StaName = ""; QString RoadName = ""; QString AllName = ""; for(int i=m_PFileInfo[index].pDBF->First();i>=0;i=m_PFileInfo[index].pDBF->Next()) { if(m_PFileInfo[index].pDBF->dbf_get(FieldRoadNo, iRoadNo) >=0 && m_PFileInfo[index].pDBF->dbf_get(FieldStaNo, iStaNo) >=0){ if(iRoadNo == RoadNo && iStaNo == StaNo){ if((m_PFileInfo[index].pDBF->dbf_get("RoadName", RoadName) >=0)&& (m_PFileInfo[index].pDBF->dbf_get("StaName", StaName) >=0)){ if(bIncludeRoadName){ AllName = RoadName + "-" + StaName; }else{ AllName = StaName; } return AllName; } } } }; return QString(""); } QString CParamMan::GetRoadName(int RoadNo) { QMutexLocker lock(&m_Mutex); int index = GetIndex(PFILE_ID_STATION, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return QString(""); } if((m_PFileInfo[index].pDBF == nullptr) || (m_PFileInfo[index].pDBF->IsOpened() == false)) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return QString(""); } int FieldRoadNo = m_PFileInfo[index].pDBF->GetFieldIndex("RoadNo"); qint64 iRoadNo; for(int i=m_PFileInfo[index].pDBF->First();i>=0;i=m_PFileInfo[index].pDBF->Next()) { if(m_PFileInfo[index].pDBF->dbf_get(FieldRoadNo, iRoadNo) >=0){ if(iRoadNo == RoadNo){ return m_PFileInfo[index].pDBF->GetFieldValue("RoadName"); } } }; return ""; } bool CParamMan::BasicInfoIdFind(const QString &Id, QString &Hex, QString &Name) { QMutexLocker lock(&m_Mutex); int index = GetIndex(PFILE_ID_BASICINFO, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return false; } if(m_PFileInfo[index].hHash == nullptr) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return false; } QString strResult; if(HASH_Find3(m_PFileInfo[index].hHash, QString("ID='%1'").arg(Id), strResult)) { //QJsonDocument doc = QJsonDocument::fromJson(strResult.toUtf8(), nullptr); //QJsonObject obj = doc.object(); //Hex = obj["HEX"].toString(); //Name = obj["NAME"].toString(); QJsonObject obj; QJsonParseError je; QJsonDocument doc = QJsonDocument::fromJson(strResult.toUtf8(), &je); if(je.error == 0) { obj = doc.object(); QJsonArray ja = obj["DATA"].toArray(); if(ja.count() > 0) { QJsonObject objStatus= ja.at(0).toObject(); Hex = objStatus["HEX"].toString(); Name = objStatus["NAME"].toString(); return true; }else{ WRITE_LOG("DATA数组为空,JsonStr=%s", strResult.toUtf8().data()); } }else{ WRITE_LOG("JSON解析失败,JsonStr=%s", strResult.toUtf8().data()); } return false; } WRITE_LOG("基础信息查找失败,Id=%s", Id.toUtf8().data()); return false; } bool CParamMan::BasicInfoHexFind(const QString &Hex, QString &Id, QString &Name) { QMutexLocker lock(&m_Mutex); int index = GetIndex(PFILE_ID_BASICINFO, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return false; } if(m_PFileInfo[index].hHash == nullptr) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return false; } QString strResult(""); if(HASH_Find3(m_PFileInfo[index].hHash, QString("HEX='%1'").arg(Hex.toUpper()), strResult)) { QJsonObject obj; QJsonParseError je; QJsonDocument doc = QJsonDocument::fromJson(strResult.toUtf8(), &je); if(je.error == 0) { obj = doc.object(); QJsonArray ja = obj["DATA"].toArray(); if(ja.count() > 0) { QJsonObject objStatus= ja.at(0).toObject(); Id = objStatus["ID"].toString(); Name = objStatus["NAME"].toString(); return true; }else{ WRITE_LOG("DATA数组为空,JsonStr=%s", strResult.toUtf8().data()); } }else{ WRITE_LOG("JSON解析失败,JsonStr=%s", strResult.toUtf8().data()); } return false; } WRITE_LOG("基础信息查找失败,hex=%s", Hex.toUtf8().data()); return false; } //bool CParamMan::StationIdFind(const int AreaNo, const int RoadNo, const int StaNo, QString &Id, QString &Name) //{ // QString StationHex = GetStationHex(AreaNo, RoadNo, StaNo); // return BasicInfoHexFind(StationHex, Id, Name); //} QString CParamMan::LaneIdFind(const QString &enStationId, const int AreaNo, const int RoadNo, const int StaNo,const int LaneNo) { QString Id, Name; QString LaneHex = GetLaneHex(AreaNo, RoadNo, StaNo, LaneNo); if(BasicInfoHexFind(LaneHex, Id, Name)) { return Id; } for(int i=0;i<255;i++) { LaneHex = GetLaneHex(AreaNo, RoadNo, StaNo, i+1); if(BasicInfoHexFind(LaneHex, Id, Name)) { return Id; } } Id = enStationId + QString("1010010"); return Id; } bool CParamMan::IssuerCheck(const QString &Issuer, const QString &issuerCode4) { QMutexLocker lock(&m_Mutex); int index = GetIndex(PFILE_ID_ISSUER_LIST, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return false; } if((m_PFileInfo[index].pDBF == nullptr) || (m_PFileInfo[index].pDBF->IsOpened() == false)) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return false; } LibDBF *p = m_PFileInfo[index].pDBF; int idxBName = p->GetFieldIndex("BRIEFNAME"); int idxStartTime = p->GetFieldIndex("STARTTIME"); int idxEndTime = p->GetFieldIndex("ENDTIME"); int idxIssuerCode = p->GetFieldIndex("NETNO"); QString dtStr = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); QString BName; QString startTime; QString endTime; QString netNo; for(int i=p->First();i>=0;i=p->Next()) { if(p->dbf_get(idxBName, BName) >=0 && p->dbf_get(idxStartTime, startTime) >=0 && p->dbf_get(idxEndTime, endTime) >=0 && p->dbf_get(idxIssuerCode, netNo) >= 0) { //WriteLog("[IssuerCheck]BName=" + BName + ",StartTime="+StartTime + ",Endtime=" + EndTime); if(BName.compare(Issuer, Qt::CaseInsensitive) == 0 && netNo.compare(issuerCode4, Qt::CaseInsensitive) == 0 && startTime.compare(dtStr) <= 0 && endTime.compare(dtStr) >= 0) { return true; } } }; WRITE_LOG("发行方查找失败,Issuer=%s", Issuer.toUtf8().data()); return false; } bool CParamMan::CardValid(const QString &cardIssuer,const QString &cardIssuerCode4, const QString &startTime, const QString &endTime, const int cardType, const int cardVehType, int &ErrorCode, QString &ErrorInfo) { //1.卡发行方判定 qint64 ProvCode = 0; if(IssuerCheck(cardIssuer, cardIssuerCode4) != true) { ErrorCode = ERROR_CODE_BASE_CARD + 0x01; ErrorInfo = "卡发行方无效,[发行方]" + cardIssuer; return false; } //2卡有效期判定 // QString CardStartTime(""); // QString CardEndTime(""); // if(m_OBUCardInfo.b4Type == 1) // { // CCPUFile0015 *pFile0015 = (CCPUFile0015 *)m_OBUCardInfo.b4Lane.IssueInfo; // CardStartTime = Array2HexStr((unsigned char *)pFile0015->PRO_CardReleTime, 4, false); // CardEndTime = Array2HexStr((unsigned char *)pFile0015->PRO_CardEndTime, 4, false); // } // if(m_OBUCardInfo.b4Type == 2) // { // CCPUFile0015 *pFile0015 = (CCPUFile0015 *)m_OBUCardInfo.b4Ass.CardInfo.b4ETC.IssueInfo; // CardStartTime = Array2HexStr((unsigned char *)pFile0015->PRO_CardReleTime, 4, false); // CardEndTime = Array2HexStr((unsigned char *)pFile0015->PRO_CardEndTime, 4, false); // } QString strDT = QDateTime::currentDateTime().toString("yyyyMMdd"); if(!(strDT.compare(startTime) >= 0 && strDT.compare(endTime) < 0)) { ErrorCode = ERROR_CODE_BASE_CARD + 0x02; ErrorInfo = "OBU不在有效期,[启用日期]" + startTime + "[停用日期]" + endTime; return false; } //ErrorInfo = "[启用日期]" + startDate + "[停用日期]" + endDate; if(!(cardType == CARD_TYPE_STORE || cardType == CARD_TYPE_TOLLY)) { ErrorCode = ERROR_CODE_BASE_CARD + 0x03; ErrorInfo = QString("无效卡类型:%1").arg(cardType); return false; } //是否判定卡内车型??????? if(IsVehTypeValid(cardVehType) == false) { ErrorCode = ERROR_CODE_BASE_CARD + 0x04; ErrorInfo = QString("卡内车型无效:%1").arg(cardVehType); return false; } return true; } QString CParamMan::GetOBUReasonText(const int iStatus) { QString reasonText = "未知原因"; for(int i=0;i<31;i++) { if((iStatus & (1 << i)) != 0) { switch(i) { case 0: reasonText = "标签挂失"; break; case 1: reasonText = "无签挂起"; break; case 2: reasonText = "无签注销"; break; case 3: reasonText = "车型不符"; break; case 4: reasonText = "核销"; break; case 5: reasonText = "挂起"; break; case 6: reasonText = "未关联扣款渠道"; break; case 7: reasonText = "账户透支"; break; case 8: reasonText = "支付机构限制使用"; break; } } } return reasonText; } QString CParamMan::GetCardReasonText(const int iStatus) { QString reasonText = "未知原因"; for(int i=0;i<31;i++) { if((iStatus & (1 << i)) != 0) { switch(i) { case 0: reasonText = "卡挂失"; break; case 1: reasonText = "无卡挂起"; break; case 2: reasonText = "无卡注销"; break; case 3: reasonText = "欠费"; break; case 4: reasonText = "合作机构黑名单"; break; case 5: reasonText = "车型不符"; break; case 6: reasonText = "储值卡余额不足"; break; } } } return reasonText; } QString CParamMan::GetVehBlackReasonText(const int iStatus) { QString reasonText = "未知原因"; for(int i=0;i<31;i++) { if((iStatus & (1 << i)) != 0) { switch(i) { case 0: reasonText = "闯关"; break; case 1: reasonText = "换卡"; break; case 2: reasonText = "丢卡"; break; case 3: reasonText = "恶意U行"; break; case 4: reasonText = "损坏设施逃逸"; break; case 5: reasonText = "协查车辆"; break; case 6: reasonText = "假军车"; break; case 7: reasonText = "假冒优惠车"; break; case 8: reasonText = "绿色通道黑名单"; break; case 9: reasonText = "恶意大车小标"; break; case 10: reasonText = "ETC长期欠费"; break; case 11: reasonText = "ETC大额欠费"; break; } } } return reasonText; } QString CParamMan::GetVehGrayReasonText(const int iStatus) { QString reasonText = "未知原因"; for(int i=0;i<31;i++) { if((iStatus & (1 << i)) != 0) { switch(i) { case 0: reasonText = "闯关"; break; case 1: reasonText = "换卡"; break; case 2: reasonText = "丢卡"; break; case 3: reasonText = "恶意影响称重"; break; case 4: reasonText = "恶意U行"; break; case 5: reasonText = "损坏设施逃逸"; break; case 6: reasonText = "持假证"; break; case 7: reasonText = "假军车"; break; case 8: reasonText = "假冒优惠车"; break; case 9: reasonText = "假冒绿通车"; break; case 10: reasonText = "车型变化"; break; case 11: reasonText = "重点车型"; break; case 12: reasonText = "大车小标"; break; case 13: reasonText = "ETC欠费"; break; } } } return reasonText; } QString CParamMan::GetSNReasonText(const QString &Status) { QString strReason("未知原因"); int iSepPos = Status.indexOf("_"); int iStatus = Status.left(iSepPos).toInt() * 10000 + Status.right(Status.length() - iSepPos - 1).toInt(); switch(iStatus) { case 10010001: strReason = "货车改客车"; break; case 10010002: strReason = "专项作业车改客车"; break; case 10010003: strReason = "多次超载";break; case 10010004: strReason = "恶意大车小标"; break; case 10010005: strReason = "客货混标";break; case 10010006: strReason = "出入口车型不符";break; case 10010007: strReason = "其它改变车型车种逃费";break; case 10020001: strReason = "倒换卡";break; case 10020002: strReason = "有入无出";break; case 10020003: strReason = "闯关";break; case 10020004: strReason = "私开道口";break; case 10020005: strReason = "网内循环行驶(超时停留)";break; case 10020006: strReason = "屏蔽计费设备";break; case 10020007: strReason = "假冒计费信息";break; case 10020008: strReason = "其它改变缴费路径逃费";break; case 10030001: strReason = "假冒军警车";break; case 10030002: strReason = "假冒紧急车";break; case 10030003: strReason = "假冒联合收割机";break; case 10030004: strReason = "假冒应急车";break; case 10030005: strReason = "假冒绿通车";break; case 10030006: strReason = "假冒应急车";break; case 10030007: strReason = "其它假冒优惠车辆逃费";break; case 10040001: strReason = "恶意U/J形行驶";break; case 10040002: strReason = "车牌不符";break; case 10040003: strReason = "一车多签(卡)";break; case 10040004: strReason = "不可达(合理)路径";break; case 10040005: strReason = "遮挡车牌";break; case 10040006: strReason = "套用车牌";break; case 10040007: strReason = "假车牌";break; case 10040008: strReason = "无车牌";break; case 10040009: strReason = "假通行卡";break; case 10040010: strReason = "假冒OBU";break; case 10040011: strReason = "假冒非现金卡";break; case 10040012: strReason = "移动OBU";break; case 10040013: strReason = "互换OBU";break; case 10040014: strReason = "多次出口丢卡";break; case 10040015: strReason = "多次入口信息覆盖";break; case 10040016: strReason = "其它";break; } return strReason; } bool CParamMan::GetBigAppointInfo(const QString resultStr, QString &CertNo, QString &Roads, QString &Goods, QString &StartDate, QString &EndDate) { QJsonObject obj; QJsonParseError je; QJsonDocument doc = QJsonDocument::fromJson(resultStr.toUtf8(), &je); if(je.error == 0) { obj = doc.object(); QJsonArray ja = obj["DATA"].toArray(); if(ja.count() > 0) { //取最后一条 QJsonObject objStatus= ja.at(ja.count() - 1).toObject(); QString Operation = objStatus["OPERATION"].toString(); if(Operation.compare("1") == 0 || Operation.compare("2") == 0) { CertNo = objStatus["CERTNO"].toString(); Roads = objStatus["ROADS1"].toString() + objStatus["ROADS2"].toString() + objStatus["ROADS3"].toString(); Goods = objStatus["GOODSINFO"].toString(); StartDate = objStatus["STARTDATE"].toString(); EndDate = objStatus["ENDDATE"].toString(); SHOWINFO(INFO_NORMAL, QString("[大件预约]编号:%1").arg(CertNo)); SHOWINFO(INFO_NORMAL, QString("[大件预约]路线:%1").arg(Roads)); SHOWINFO(INFO_NORMAL, QString("[大件预约]货物:%1").arg(Goods)); SHOWINFO(INFO_NORMAL, QString("[大件预约]日期:%1-%2").arg(StartDate, EndDate)); return true; } }else{ WRITE_LOG("DATA无数据,JsonStr=%s", resultStr.toUtf8().data()); } }else{ WRITE_LOG("JSON解析失败,JsonStr=%s", resultStr.toUtf8().data()); } return false; } bool CParamMan::GetEmerCarInfo(const QString resultStr, QString &Id, int &VehSign, QString &DiscountInfo, QString &StartDate, QString &EndDate) { QJsonObject obj; QJsonParseError je; QJsonDocument doc = QJsonDocument::fromJson(resultStr.toUtf8(), &je); if(je.error == 0) { obj = doc.object(); QJsonArray ja = obj["DATA"].toArray(); if(ja.count() > 0) { //取最后一条 QJsonObject objRecord= ja.at(ja.count() - 1).toObject(); Id = objRecord["ID"].toString(); VehSign = objRecord["VEHSIGN"].toInt(); DiscountInfo = objRecord["DISCOUNTIN"].toString(); StartDate = objRecord["STARTTIME"].toString(); EndDate = objRecord["ENDTIME"].toString(); return true; }else{ WRITE_LOG("DATA无数据,JsonStr=%s", resultStr.toUtf8().data()); } }else{ WRITE_LOG("JSON解析失败,JsonStr=%s", resultStr.toUtf8().data()); } return false; } bool CParamMan::GetGreenCarInfo(const QString resultStr, QString &Id, QString &StartDate, QString &AppTime) { QJsonObject obj; QJsonParseError je; QJsonDocument doc = QJsonDocument::fromJson(resultStr.toUtf8(), &je); if(je.error == 0) { obj = doc.object(); QJsonArray ja = obj["DATA"].toArray(); if(ja.count() > 0) { //取最后一条 QJsonObject objRecord= ja.at(ja.count() - 1).toObject(); Id = objRecord["ID"].toString(); StartDate = objRecord["STARTTIME"].toString(); AppTime = objRecord["APPTIME"].toString(); return true; }else{ WRITE_LOG("DATA无数据,JsonStr=%s", resultStr.toUtf8().data()); } }else{ WRITE_LOG("JSON解析失败,JsonStr=%s", resultStr.toUtf8().data()); } return false; } bool CParamMan::doFindBlack(const uint PFileId,const QString &SearchStr, QString &ResultStr) { int index = GetIndex(PFileId, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return false; } if(m_PFileInfo[index].hHash == nullptr) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return false; } return HASH_Find2(m_PFileInfo[index].hHash, SearchStr, ResultStr); } bool myfunction(CBlackItem itemA,CBlackItem itemB) { return (itemA.CreateTime < itemB.CreateTime); } int CParamMan::GetBlackStatus(int statusAll, const qint64 &dtAllVer, const QString &resultInc) { vector vBlackInc; if(GetBlackIncStatus(dtAllVer, resultInc, "CREATETIME", "STATUS", "BACKUP1", vBlackInc) > 0) { std::sort(vBlackInc.begin(), vBlackInc.end(), myfunction); for(int i=0;i &v) { v.clear(); QJsonObject obj; QJsonParseError je; QJsonDocument doc = QJsonDocument::fromJson(resultStr.toUtf8(), &je); if(je.error == 0) { obj = doc.object(); QJsonArray ja = obj["DATA"].toArray(); for(int i=0;i= dtAllVer) { CBlackItem item; item.CreateTime = dtCreateTime; item.Status = objStatus[fnStatus].toString().toInt(); item.State = objStatus[fnState].toString().toInt(); v.insert(v.begin(), item); } } }else{ WRITE_LOG("JSON解析失败,JsonStr=%s", resultStr.toUtf8().data()); } return v.size(); } int CParamMan::GetBlackAllStatus(const QString &resultStr, const QString &StatusFieldName) { QJsonObject obj; QJsonParseError je; QJsonDocument doc = QJsonDocument::fromJson(resultStr.toUtf8(), &je); if(je.error == 0) { obj = doc.object(); QJsonArray ja = obj["DATA"].toArray(); if(ja.count() > 0) { QJsonObject objStatus= ja.at(0).toObject(); return objStatus[StatusFieldName].toString().toInt(); }else{ WRITE_LOG("DATA数组为空,JsonStr=%s", resultStr.toUtf8().data()); } }else{ WRITE_LOG("JSON解析失败,JsonStr=%s", resultStr.toUtf8().data()); } return 0; } //获取全量增量状态 int CParamMan::GetBlackAllInc(const int PFileIdAll, const int PFileIdInc,const QString &Id) { QString VerAll = GetBaseInfo(PFileIdAll, m_LocalRoadNo, m_LocalStaNo, 1); QString VerInc = GetBaseInfo(PFileIdInc, m_LocalRoadNo, m_LocalStaNo, 1); if(VerAll.compare(VerInc) > 0) { QString resultAll; if(doFindBlack(PFileIdAll, Id, resultAll)) { int Status = GetBlackAllStatus(resultAll, "STATUS"); return Status; } }else{ int statusAll = 0; QString resultAll; if(doFindBlack(PFileIdAll, Id, resultAll)) { statusAll = GetBlackAllStatus(resultAll, "STATUS"); } QString resultInc; if(doFindBlack(PFileIdInc, Id, resultInc)) { qint64 dtVerAll = QDateTime::fromString(VerAll.left(6), "yyMMdd").toMSecsSinceEpoch(); statusAll = GetBlackStatus(statusAll, dtVerAll, resultInc); } return statusAll; } return 0; } QString CParamMan::GtSNAllReason(const QString &resultStr, const QString &fnReason) { QString strReasonInfo; QJsonObject obj; QJsonParseError je; QJsonDocument doc = QJsonDocument::fromJson(resultStr.toUtf8(), &je); if(je.error == 0) { obj = doc.object(); QJsonArray ja = obj["DATA"].toArray(); if(ja.count() > 0) { QJsonObject objStatus= ja.at(0).toObject(); QStringList lstReason = objStatus[fnReason].toString().split("|"); for(int i= 0;i dtMax) { dtMax = dtCreateTime; iState = objStatus[fnState].toString().toInt(); strReason = objStatus[fnReason].toString(); iOWEFee = objStatus[fnOWEFee].toString().toInt(); } } QStringList lstReason = strReason.split("|"); for(int i= 0;i 0) { QString resultAll; if(doFindBlack(PFileIdAll, VehicleId, resultAll)) { ErrorInfo = GtSNAllReason(resultAll, QString("REASON")); return true; } }else{ QString resultInc; if(doFindBlack(PFileIdInc, VehicleId, resultInc)) { //增量名单找到了,不需要找全量名单 return GtSNIncReason(resultInc, "CREATETIME", "REASON", "STATUS", "OWEFEE", ErrorInfo) == 1; } QString resultAll; if(doFindBlack(PFileIdAll, VehicleId, resultAll)) { ErrorInfo = GtSNAllReason(resultAll, "REASON"); return true; } } return false; } //OBU黑名单 OBU合同序号含发行方 bool CParamMan::IsOBUBlack(const QString &OBUContractSerialNumber, QString &ErrorInfo) { QMutexLocker lock(&m_Mutex); int statusAll = GetBlackAllInc(PFILE_ID_OBUBLACK, PFILE_ID_OBUBLACKINC, OBUContractSerialNumber); if(statusAll != 0) { ErrorInfo = GetOBUReasonText(statusAll); WRITE_LOG("OBU黑名单:%s:%s", OBUContractSerialNumber.toUtf8().data(), ErrorInfo.toUtf8().data()); return true; } return false; } //CPU卡黑名单 bool CParamMan::IsCardBlack(const QString &CardNo, QString &ErrorInfo) { QMutexLocker lock(&m_Mutex); int statusAll = GetBlackAllInc(PFILE_ID_CARDBLACKLIST, PFILE_ID_CARDBLACKLISTINC, CardNo); if(statusAll != 0) { ErrorInfo = GetCardReasonText(statusAll); WRITE_LOG("CPU黑名单:%s:%s", CardNo.toUtf8().data(), ErrorInfo.toUtf8().data()); return true; } return false; } //省内车牌黑名单 bool CParamMan::IsVehicleInProvBlack(const QString &VehPlate, QString &ErrorInfo) { // QMutexLocker lock(&m_Mutex); // QString resultAll; // QString verAll = "0"; // QString reasonAll = "0"; // bool bResultAll = doFindBlack(PFILE_ID_, CarNo, resultAll); // if(bResultAll) // { // verAll = GetReason(resultAll, "VEHID", "STATUS", reasonAll); // } // if(verAll.compare("0") > 0) // { // ErrorInfo = GetCardReasonText(reasonAll); // return true; // } ErrorInfo = "正常"; return false; } //车牌黑名单按照部中心文档,现在这个停用了 bool CParamMan::IsVehicleBlack(const QString &VehPlateAll, QString &ErrorInfo) { QMutexLocker lock(&m_Mutex); int statusAll = GetBlackAllInc(PFILE_ID_VEHICLEBLACK, PFILE_ID_VEHICLEBLACKINC, VehPlateAll); if(statusAll != 0) { ErrorInfo = GetVehBlackReasonText(statusAll); return true; } return false; } bool CParamMan::IsSNBlack(const QString &VehPlateAll, QString &ErrorInfo) { QMutexLocker lock(&m_Mutex); if(GetSNAllInc(PFILE_ID_SNBLACKLIST, PFILE_ID_SNBLACKLISTINC, VehPlateAll, ErrorInfo)) { WRITE_LOG("信用黑名单:%s:%s", VehPlateAll.toUtf8().data(), ErrorInfo.toUtf8().data()); return true; } return false; } //大件车黑名单 bool CParamMan::IsBigBlack(const QString &VehPlate, QString &ErrorInfo) { QMutexLocker lock(&m_Mutex); QString resultAll; if(doFindBlack(PFILE_ID_BIGBLACK, VehPlate, resultAll)) { ErrorInfo = QString("大件车黑名单"); WRITE_LOG("大件黑名单:%s:%s", VehPlate.toUtf8().data(), resultAll.toUtf8().data()); return true; } return false; } //是否大件运输 bool CParamMan::IsBigAppoint(const QString &VehPlateAll, QString &CertNo, QString &Roads, QString &Goods, QString &StartDate, QString &EndDate) { QMutexLocker lock(&m_Mutex); QString resultAll; if(doFindBlack(PFILE_ID_BIGAPPOINT, VehPlateAll, resultAll)) { return GetBigAppointInfo(resultAll, CertNo, Roads, Goods, StartDate, EndDate); } return false; } //是否抢险救灾 bool CParamMan::IsEmerCar(const QString &VehPlateAll, QString &Id, int &VehSign, QString &DiscountInfo, QString &StartDate, QString &EndDate) { QMutexLocker lock(&m_Mutex); QString resultAll; if(doFindBlack(PFILE_ID_EMERCARALL, VehPlateAll, resultAll)) { return GetEmerCarInfo(resultAll, Id, VehSign, DiscountInfo, StartDate, EndDate); } if(doFindBlack(PFILE_ID_EMERCARINC, VehPlateAll, resultAll)) { return GetEmerCarInfo(resultAll, Id, VehSign, DiscountInfo, StartDate, EndDate); } return false; } bool CParamMan::IsGreenCar(const QString &VehPlateAll, QString &Id, QString &StartDate, QString &AppTime) { QMutexLocker lock(&m_Mutex); QString resultAll; if(doFindBlack(PFILE_ID_GAPPOINTALL, VehPlateAll, resultAll)) { return GetGreenCarInfo(resultAll, Id, StartDate, AppTime); } if(doFindBlack(PFILE_ID_GAPPOINTINC, VehPlateAll, resultAll)) { return GetGreenCarInfo(resultAll, Id, StartDate, AppTime); } return false; } //计算自动班次 //返回值:0当前班次=前一班次 // 1当前班次>前一班次 // -1班次表错误,无法定位到班次 int CParamMan::GetAutoClassInfo(QDateTime &LastClassDate, int &LastClassNo) { QMutexLocker lock(&m_Mutex); QDateTime now = QDateTime::currentDateTime(); QString time = now.toString("hhmmss"); QDateTime date = QDateTime::fromString(now.toString("yyyyMMdd"), "yyyyMMdd"); int index = GetIndex(PFILE_ID_SQUAD, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return -1001; } if((m_PFileInfo[index].pDBF == nullptr) || (m_PFileInfo[index].pDBF->IsOpened() == false)) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return -1002; } LibDBF *pDBF = m_PFileInfo[index].pDBF; for(int i=pDBF->First();i>=0;i=pDBF->Next()) { qint64 iClassNo, iStep; QString BegDT, EndDT; QDateTime dtBegDT, dtEndDT; QString ClassName; pDBF->dbf_get("CLASSNO", iClassNo); pDBF->dbf_get("STEP", iStep); pDBF->dbf_get("BEGDT", BegDT); pDBF->dbf_get("ENDDT", EndDT); pDBF->dbf_get("CLASSNAME", ClassName); dtBegDT = Str2DateTime(BegDT); BegDT = dtBegDT.toString("hhmmss"); dtEndDT = Str2DateTime(EndDT); EndDT = dtEndDT.toString("hhmmss"); if(time.compare(BegDT) >= 0 && time.compare(EndDT) <= 0) { //落在该区域 date = date.addDays(iStep); if(date < LastClassDate) { //前一工班日大于当前工班日,不修改班次信息 return 0; }else{ if(date == LastClassDate) { //前一工班日和当前工班日相等 if(iClassNo > LastClassNo) { //当前班次大于前一班次 LastClassNo = iClassNo; return 1; }else{ //当前班次小于前一班次 return 0; } }else{ LastClassDate = date; LastClassNo = iClassNo; return 1; } } } }; return -1003; } //获取可选班次 //返回值:返回可选工班的数量 int CParamMan::GetOptionalClassInfo(const QDateTime &dt, QDateTime *pClassDate, int *pClassNo, QString *pClassName) { QMutexLocker lock(&m_Mutex); QString dtString = dt.toString("hhmmss"); QDateTime dtDate = QDateTime::fromString(dt.toString("yyyyMMdd"), "yyyyMMdd"); int OptCount = 0; QDateTime LastClassDate = QDateTime::fromString("20000101","yyyyMMdd"); int LastClassNo = 0; qint64 iClassNo, iStep; QString BegDT1, EndDT1, BegDT2, EndDT2; QDateTime dtBegDT, dtEndDT; QString ClassName; int index = GetIndex(PFILE_ID_SQUAD, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return -1001; } if((m_PFileInfo[index].pDBF == nullptr) || (m_PFileInfo[index].pDBF->IsOpened() == false)) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return -1002; } LibDBF *pDBF = m_PFileInfo[index].pDBF; for(int i=pDBF->First();i>=0;i=pDBF->Next()) { pDBF->dbf_get("CLASSNO", iClassNo); pDBF->dbf_get("STEP", iStep); pDBF->dbf_get("BEGDT", BegDT1); pDBF->dbf_get("ENDDT", EndDT1); pDBF->dbf_get("CLASSNAME", ClassName); dtBegDT = Str2DateTime(BegDT1); dtBegDT = Str2DateTime(dtDate.toString("yyyyMMdd") + dtBegDT.toString("hhmmss")); dtBegDT = dtBegDT.addSecs(- STEP_TIME * 60); //BegDT1 = dtBegDT.toString("hhmmss"); dtEndDT = Str2DateTime(EndDT1); dtEndDT = Str2DateTime(dtDate.toString("yyyyMMdd") + dtEndDT.toString("hhmmss")); //EndDT1 = dtEndDT.toString("yyyyMMddhhmmss"); bool bStepADay = false; if(dtBegDT.daysTo(dtEndDT) != 0) { //向前调整时间,结果跨天了 BegDT1 = dtBegDT.toString("hhmmss"); EndDT1 = QString("235959"); //当天的最后一秒 BegDT2 = QString("000000"); //第二天第一秒 EndDT2 = dtEndDT.toString("hhmmss"); bStepADay = true; }else{ BegDT1 = dtBegDT.toString("hhmmss"); EndDT1 = dtEndDT.toString("hhmmss"); BegDT2 = BegDT1; EndDT2 = EndDT1; } if((dtString.compare(BegDT1) >= 0 && dtString.compare(EndDT1) <= 0) || (dtString.compare(BegDT2) >= 0 && dtString.compare(EndDT2) <= 0)) { //落在该区域 QDateTime ClassDate = dtDate.addDays(iStep); if((dtDate.secsTo(dt) > 20*60*60) && bStepADay) { //24点前 if(iStep < 0) { ClassDate = dtDate; } if(iStep == 0) { ClassDate = dtDate.addDays(1); } } //int ClassNo = iClassNo; if(!(ClassDate == LastClassDate && iClassNo == LastClassNo)) { if(OptCount == 0) { pClassDate[0] = ClassDate; pClassNo[0] = iClassNo; pClassName[0] = ClassName; }else{ //工班大小排序 QString strClass1 = QString("%1%2").arg(pClassDate[0].toString("yyyyMMdd")).arg(pClassNo[0]); QString strClass2 = QString("%1%2").arg(ClassDate.toString("yyyyMMdd")).arg(iClassNo); if(strClass1.compare(strClass2) > 0) { for(int k=OptCount;k>0;k--) { pClassDate[k] = pClassDate[k-1]; pClassNo[k] = pClassNo[k-1]; pClassName[k] = pClassName[k-1]; } pClassDate[0] = ClassDate; pClassNo[0] = iClassNo; pClassName[0] = ClassName; }else{ pClassDate[OptCount] = ClassDate; pClassNo[OptCount] = iClassNo; pClassName[OptCount] = ClassName; } } LastClassDate = ClassDate; LastClassNo = iClassNo; OptCount++; } } }; return OptCount; } QString CParamMan::GetClassCName(const int ClassNo) { QMutexLocker lock(&m_Mutex); int index = GetIndex(PFILE_ID_SQUAD, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return QString("未知"); } if((m_PFileInfo[index].pDBF == nullptr) || (m_PFileInfo[index].pDBF->IsOpened() == false)) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return QString("未知"); } LibDBF *pDBF = m_PFileInfo[index].pDBF; for(int i=pDBF->First();i>=0;i=pDBF->Next()) { qint64 iClassNo; QString ClassName; pDBF->dbf_get("CLASSNO", iClassNo); pDBF->dbf_get("CLASSNAME", ClassName); if(iClassNo == ClassNo) { return ClassName; } }; return ""; } //返回值1--正常 0--该参数不加载 其他--错误 int CParamMan::CheckTempParamValid(const CPFileInfo &fileInfo, const QString &srcFileName,const QString &dstFileName, const bool bShowInfo) { if(!CHECKLOADMODE(fileInfo.LoadMode, fileInfo.PFileId)) { return 0; } QFileInfo fi(srcFileName); if(!fi.exists()) { //不存在 if(bShowInfo) { WRITE_LOG("参数校验[%s]失败,文件不存在,FileName=%s", fileInfo.PFileCName.toUtf8().data(), srcFileName.toUtf8().data()); SHOWINFO(INFO_WARNING, QString("参数校验[%1]失败,文件不存在").arg(fileInfo.PFileCName)); } return -1; } if(fi.permission(QFile::WriteOther)) { //可写 if(bShowInfo) { WRITE_LOG("参数校验[%s]失败,文件属性错误,FileName=%s", fileInfo.PFileCName.toUtf8().data(), srcFileName.toUtf8().data()); SHOWINFO(INFO_WARNING, QString("参数校验[%1]失败,文件属性错误").arg(fileInfo.PFileCName)); } return -2; } QString StrRoadNo = QString::number(fileInfo.RoadNo); QString StrStaNo = QString::number(fileInfo.StaNo); int iCheckResult = TF_FileCheck(srcFileName.toUtf8().data(), dstFileName.toUtf8().data(), fileInfo.IsCheckStartDate, fileInfo.StartDateFieldName.toUtf8().data(), fileInfo.IsCheckStation, StrRoadNo.toUtf8().data(), StrStaNo.toUtf8().data(), fileInfo.RoadNoFieldName.toUtf8().data(), fileInfo.StaNoFieldName.toUtf8().data()); if(iCheckResult != 1) { if(bShowInfo) { WRITE_LOG("参数校验[%s]失败,错误代码=%d,FileName=%s", fileInfo.PFileCName.toUtf8().data(), iCheckResult, srcFileName.toUtf8().data()); SHOWINFO(INFO_WARNING, QString("参数校验[%1]失败,错误代码=%2").arg(fileInfo.PFileCName).arg(iCheckResult)); } } WRITE_LOG("参数状态:CheckResult=%d,FileName=%s", iCheckResult, srcFileName.toUtf8().data()); return iCheckResult; } bool CParamMan::UpdateParam(CPFileInfo &fileInfo,const QString &FileCName, const QString &dstFileName, const QString &srcFileName) { if(fileInfo.IsRealUpdate) { //后台加载 QString FileExt = QString("_%1%2").arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmss"), ExtractFileExt(fileInfo.PFileName)); QString dstFileName2 = m_LibBasePath + ChangeFileExt(fileInfo.PFileName, FileExt); return LoadParamBackground(fileInfo, srcFileName, dstFileName2); }else{ if(UnLoadParam(fileInfo)) { if(TF_FileCopy(srcFileName.toUtf8().data(), dstFileName.toUtf8().data()) >= 0) { if(LoadParam(fileInfo)) { UpdateParamInfo(fileInfo.PFileId, fileInfo.RoadNo, fileInfo.StaNo, 0, FileCName, dstFileName, srcFileName); return true; } }else{ SHOWINFO(INFO_WARNING, QString("[拷贝参数文件]失败%1").arg(FileCName)); } }else{ SHOWINFO(INFO_WARNING, QString("[卸载参数文件]失败%1").arg(FileCName)); } } return false; } void CParamMan::CopyParam() { QMutexLocker lock(&m_Mutex); vector updateIdList; for(int i=0;im_cfg.IsOutPort()) { if(gLaneApp->m_cfg.IsHighway()) { QString strVer = GetBaseInfo(PFILE_ID_ROADPRICE,m_LocalRoadNo, m_LocalStaNo, 2); return strVer.right(2); }else{ return GetBaseInfo(PFILE_ID_OPENPRICE, m_LocalRoadNo, m_LocalStaNo, 1); } } return "0"; } QString CParamMan::GetRateVersion() { QMutexLocker lock(&m_Mutex); if(gLaneApp->m_cfg.IsOutPort()) { if(gLaneApp->m_cfg.IsHighway()) { return QString("%1|15%2").arg(GetBaseInfo(PFILE_ID_ROADPRICE, m_LocalRoadNo, m_LocalStaNo, 2), GetBaseInfo(PFILE_ID_ROADPRICE,m_LocalRoadNo, m_LocalStaNo, 1)); }else{ return GetBaseInfo(PFILE_ID_OPENPRICE, m_LocalRoadNo, m_LocalStaNo, 2); } } return "0"; } bool CParamMan::GetOBUOnLineFeeInfo(OBUCardInfoHelper &infoHelper,const QString &enStationId , const QString &enStationName, const QString &enLaneId, const int FeeVehType, const int AxisCount, const int Weight, CFeeCalcInfo &fee, QString &ErrorInfo) { int CardType = infoHelper.GetCardType(); CFeeCalcInfo minFee; QString exStationId = gLaneApp->GetStationId(); if(GetMinFee(enStationId, exStationId, m_LocalRoadNo, m_LocalStaNo, CardType, FeeVehType, minFee) == false) { ErrorInfo = QString("最小费额查询失败,入口站=%1(%2),exId=%3").arg(enStationName, enStationId, exStationId); SHOWINFO(INFO_ERROR, ErrorInfo); return false; } fee = minFee; //卡信息 CFeeCalcInfo onlineFee; if(gLaneApp->m_ImageQuery.GetOBUOnLineFee(infoHelper.IsMultiProv(), FeeVehType, AxisCount, Weight, enLaneId, exStationId, infoHelper, onlineFee, ErrorInfo) == 0) { //在线计费成功,比较最小费额 if(MinFeeCompare(minFee, CardType, onlineFee, ErrorInfo) == 0) { ErrorInfo = QString("在线计费成功"); fee = onlineFee; SHOWINFO(INFO_NORMAL, ErrorInfo); return true; }else{ fee = onlineFee; SHOWINFO(INFO_WARNING, ErrorInfo); } } //在线计费失败,转最小费额 SHOWINFO(INFO_WARNING, QString("%1,转最小费额").arg(ErrorInfo)); return true; } bool CParamMan::GetCPCCardFee(CardDataInfoHelper &infoHelper, const int FeeVehType, const int AxisCount, CFeeCalcInfo &fee) { if(GetCPCFee(FeeVehType, AxisCount, infoHelper.GetCPCEF01(), infoHelper.GetCPCEF02(), fee) == FEE_FLAG_SUCC) { int OutProvCashTotal, OutProvInCashTotal, OutProvMileAge; int InProvCashTotal, InProvInCashTotal, InProvMileAge; infoHelper.GetCPCFeeInCard(OutProvCashTotal, OutProvInCashTotal, OutProvMileAge, InProvCashTotal, InProvInCashTotal, InProvMileAge); fee.OutProvCashTotal = OutProvCashTotal; fee.OutProvInCashTotal = OutProvInCashTotal; fee.InProvCashTotal = fee.InProvCashTotal + InProvCashTotal; fee.InProvInCashTotal = fee.InProvInCashTotal + InProvInCashTotal; fee.FeeMileAgeTotal = fee.FeeMileAgeTotal + OutProvMileAge + InProvMileAge; fee.Cash = fee.OutProvCashTotal + fee.InProvCashTotal; fee.InCash = fee.OutProvInCashTotal + fee.InProvInCashTotal; fee.TransFee = fee.InCash; fee.TotalTransCount = infoHelper.GetGantryTransCount() + 1; fee.ProvCount = infoHelper.GetProvCount(); fee.ProvCountInCard = fee.ProvCount; //通行省份(费率模块计算出,后面不修改) fee.OutProvCashTotalInCard = fee.OutProvCashTotal; //外省累计应收金额(费率模块计算出,后面不修改) fee.OutProvInCashTotalInCard = fee.OutProvInCashTotal; //外省累计实收金额(费率模块计算出,后面不修改) fee.FeeMileAgeTotalInCard = fee.FeeMileAgeTotal; //本省计费里程(费率模块计算出,后面不修改) fee.InProvCashTotalInCard = fee.InProvCashTotal; //本省应收金额(费率模块计算出,后面不修改) fee.InProvInCashTotalInCard = fee.InProvInCashTotal; //本省实收金额 (费率模块计算出,后面不修改) fee.FeeMileAgeInCard = fee.FeeMileAge; //本次计费里程(费率模块计算出,后面不修改) return true; } return false; } int CParamMan::GetCPCCardFeeInfo(const QString &VehPlate, const int VehPlateColor, const int FeeVehType, const int AxisCount, const int Weight, const QString &enStationId, const QString &enLaneId, CardDataInfoHelper &infoHelper, const int ExitFeeType, const int ProvCount, CFeeCalcInfo &fee, QString &ErrorInfo) { //最小费额计费 int CardType = infoHelper.GetCardType(); CFeeCalcInfo minFee; QString exStationId = gLaneApp->GetStationId(); if(!GetMinFee(enStationId, exStationId, m_LocalRoadNo, m_LocalStaNo, CardType, FeeVehType, minFee)) { ErrorInfo = QString("查询最小费额失败,enId=%1,exId=%2").arg(enStationId, exStationId); return -1; } fee = minFee; int ErrorCode = -1; CFeeCalcInfo cardFee; if(ExitFeeType == EXIT_FEE_TYPE_CPC) { if(GetCPCCardFee(infoHelper, FeeVehType, AxisCount, cardFee)) { if((ErrorCode = MinFeeCompare(minFee, CardType, cardFee, ErrorInfo)) == 0) { fee = cardFee; ErrorInfo = QString("卡计费成功"); return FEE_FLAG_SUCC; }else{ fee = cardFee; //合并后,cardFee中使用了最小费额 SHOWINFO(INFO_WARNING, ErrorInfo); } }else{ SHOWINFO(INFO_WARNING, QString("卡计费失败,转在线计费")); } } CFeeCalcInfo onlineFee; if(gLaneApp->m_ImageQuery.GetCardOnLineFee(ProvCount > 1, VehPlate, VehPlateColor, FeeVehType, AxisCount, Weight, enLaneId, exStationId, infoHelper, onlineFee, ErrorInfo) == 0) { if((ErrorCode = MinFeeCompare(minFee, CardType, onlineFee, ErrorInfo)) == 0) { fee = onlineFee; ErrorInfo = QString("在线计费成功"); return FEE_FLAG_SUCC; }else{ fee = onlineFee; //合并后,cardFee中使用了最小费额 SHOWINFO(INFO_WARNING, ErrorInfo); } }else{ SHOWINFO(INFO_WARNING, ErrorInfo); } return FEE_FLAG_SUCC; } int CParamMan::GetNoCardOnLineFeeInfo(const QString &VehPlate, const int VehPlateColor, const int FeeVehType, const int AxisCount, const int Weight, const CEnStationInfo &enStation, const int CardType, CFeeCalcInfo &fee, QString &ErrorInfo) { CFeeCalcInfo minFee; QString exStationId = gLaneApp->GetStationId(); if(!GetMinFee(enStation.EnStationId, exStationId, m_LocalRoadNo, m_LocalStaNo, CardType, FeeVehType, minFee)) { ErrorInfo = QString("查询最小费额失败,enId=%1,exId=%2").arg(enStation.EnStationId, exStationId); return -1; } fee = minFee; CFeeCalcInfo noCardFee; if(gLaneApp->m_ImageQuery.GetNoCardOnLineFee(VehPlate, VehPlateColor, FeeVehType, AxisCount, Weight, enStation.EnStationId, enStation.enTime, exStationId, CardType, noCardFee, ErrorInfo) == 0) { if(MinFeeCompare(minFee, CardType, noCardFee, ErrorInfo) == 0) { fee = noCardFee; ErrorInfo = QString("在线计费成功"); return FEE_FLAG_SUCC; } fee = noCardFee; } return FEE_FLAG_SUCC; } //axleCount 出口轴数 //VehType 出口车型 //出口改轴,改车型都需要在线计费 //输入: //VehicleClassGB:国标车种 //OBUVehType: OBU车型 //pEF04 B3帧中的EF04文件 //输出: //FeeCalcResult 计费结果代码,当feeSpecial是反向时,这个值也是0,所以不能用作准确计费成功失败状态 //FeeVehType 计费车型,obu车型,轴数,入口车型一起决定计费车型 //ProvCashTotal 本省应收 //ProvInCashTotal 本省实收 //FeeMileageTotal 全程的计费里程 //返回值:计费成功FEE_FLAG_SUCC,失败FEE_FLAG_FAIL int CParamMan::GetOBUFee(const int VehicleClassGB, const int OBUVehType, const int OBUAxisCount, const COBUFileEF04 *pEF04, CFeeCalcInfo &fee) { InitFeeCalcInfo(fee); TradingInfo tradeInfo; memset(&tradeInfo, 0, sizeof(TradingInfo)); FeeInfo feeInfo; memset(&feeInfo, 0, sizeof(FeeInfo)); RoadInfo roadInfo; memset(&roadInfo, 0, sizeof(RoadInfo)); QString str = GetStationHex(m_LocalAreaNo, m_LocalRoadNo, m_LocalStaNo); strncpy(tradeInfo.curTollGantry, str.toUtf8().data(), sizeof(tradeInfo.curTollGantry)-1); //当前收费门架编码,当初始化函数中的当前门架编码为null时,应支持全省所有门架的费用查询(含代收);初始化函数中的当前门架编码不为null时,该字段与初始化函数中的当前门架编码相等。 str = QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm:ss"); strncpy(tradeInfo.curPassTime, str.toUtf8().data(), sizeof(tradeInfo.curPassTime)-1); //COBUFileEF04 *pEF04 = (COBUFileEF04 *)b3.EF04Info; tradeInfo.laneStatus = pEF04->PRO_InOutStatus; str = GetStationHex(BCD2Int(pEF04->PRO_InAreaNo), pEF04->PRO_InRoadNo, Array2Int(pEF04->PRO_InStationNo, 2)); strncpy(tradeInfo.enTollStationHex, str.toUtf8().data(), sizeof(tradeInfo.enTollStationHex)-1); str = Array2HexStr(pEF04->PRO_ETCFlagNo, 3, false); strncpy(tradeInfo.lastGantryHex, str.toUtf8().data(), sizeof(tradeInfo.lastGantryHex)-1); tradeInfo.vehicleUserType = pEF04->PRO_UserType; //前面验证了标签和卡的usertype一致性 tradeInfo.tagType = 1; //这里先固定为双片式 tradeInfo.axleCount = OBUAxisCount; //标签内的轴数 tradeInfo.enAxleCount = pEF04->PRO_AxleCount; tradeInfo.cardType = pEF04->PRO_CardType; tradeInfo.vehicleType = OBUVehType; //标签车型 tradeInfo.enVehicleType = pEF04->PRO_VehType; //入口车型 tradeInfo.vehicleClass = VehicleClassGB; //t.feeSumLocal = Array2Int(pEF04->PRO_TotalInCash, 3); tradeInfo.totalWeight = Array2Int(pEF04->PRO_TotalWeight, 3); //货车总重,单位:kg,差异化 tradeInfo.vehicleStatusFlag = pEF04->PRO_VehicleStatusFlag; //车辆状态标识。 str = Array2HexStr(pEF04->PRO_InProvHex, 3, false); strncpy(tradeInfo.feeProvBeginHex, str.toUtf8().data(), sizeof(tradeInfo.feeProvBeginHex)-1); // 本省入口ETC门架信息,(省界入口ETC门架或省内第一个ETC门架的6位HEX编码,收费站入口格式为“000000”) tradeInfo.feeProvMileage = Array2Int(pEF04->PRO_TotalFeeMiles, 3); // ETC标签EF04文件或者CPC EF02文件中的本省累计计费里程,单位:M(米) tradeInfo.payFeeSumLocal = Array2Int(pEF04->PRO_CashInProv, 3); // ETC标签EF04文件中读出的本省累计应收金额,CPC卡EF02文件中读出的本省累计金额,单位:分 tradeInfo.realFeeSumLocal = Array2Int(pEF04->PRO_TotalInCashInProv, 3); // ETC标签EF04文件中读出的本省累计实收金额,单位:分,默认填-1 表示此字段无效。 int FeeCalcResult = getStaFee(tradeInfo, feeInfo, nullptr, roadInfo, 0); if(FeeCalcResult == 0 && strcmp(feeInfo.feeSpecial, "") == 0) { fee.ExitFeeType = EXIT_FEE_TYPE_OBU; fee.FeeCalcResult = FeeCalcResult; fee.InProvCashTotal = feeInfo.feeSpare1; fee.InProvInCashTotal = feeInfo.feeProvSumLocal; fee.FeeMileAgeTotal = feeInfo.feeSpare2; //计费里程是总里程吗?好像不能区分本省计费里程 fee.FeeMileAge = feeInfo.feeMileage; //本次计费里程 fee.FeeVehType = feeInfo.feeVehicleType; strncpy(fee.FeeSpecial , feeInfo.feeSpecial, sizeof(fee.FeeSpecial)-1); fee.TollFeeCheck = feeInfo.feeProvSumLocal; //fee.FeeSpare1 = feeInfo.feeSpare1; fee.PayFee = feeInfo.payFee; fee.Fee = feeInfo.realFee; strncpy(fee.tollintervalid, feeInfo.tollIntervalIDs, sizeof(fee.tollintervalid)-1); //计费单元id strncpy(fee.payFeeGroup, feeInfo.payFeeGroup, sizeof(fee.payFeeGroup)-1); // 收费单元应收金额(优惠前金额)组合,单位:分,若有代收用"|"分隔。如:"1000|2000"表示按照tollIntervalIDs中先后出现的两个收费单元分别应收费(优惠前)10元和20元。 strncpy(fee.discountFeeGroup, feeInfo.discountFeeGroup, sizeof(fee.discountFeeGroup)-1); //收费单元优惠金额组合,单位:分,若有代收用"|"分隔。如:"200|700"表示按照tollIntervalIDs中先后出现的两个收费单元分别应优惠2元和7元。 strncpy(fee.feeGroup, feeInfo.feeGroup, sizeof(fee.feeGroup)-1); //交易金额(应收金额减去优惠金额)组合,单位:分,若有代收用"|"分隔。如:"800|1300"表示按照tollIntervalIDs中先后出现的两个收费单元交易金额分别为8元和13元。 strncpy(fee.feeInfo1, feeInfo.feeInfo1, sizeof(fee.feeInfo1)-1); //计费信息1,省份自定义,utf-8编码(若有汉字)计费模块可以使用自定义字段(计费信息1、2、3)返回优惠率、优惠类型及说明、错误码或特情等信息,该信息会在交易流水中上传省中心,用于省中心的自定义分析。推荐参照前面字段的样式。 strncpy(fee.feeInfo2, feeInfo.feeInfo2, sizeof(fee.feeInfo2)-1); //计费信息2,省份自定义,utf-8编码(若有汉字) strncpy(fee.feeInfo3, feeInfo.feeInfo3, sizeof(fee.feeInfo3)-1); //fee.FeeFlag = FEE_FLAG_SUCC; WRITE_LOG("计费成功:feeInfo1=%s,feeInfo2=%s,feeInfo3=%s", fee.feeInfo1, fee.feeInfo2, fee.feeInfo3); return FEE_FLAG_SUCC; } //fee.FeeFlag = FEE_FLAG_FAIL; WRITE_LOG("计费失败:calcResult=%d,feeInfo1=%s,feeInfo2=%s,feeInfo3=%s", FeeCalcResult, fee.feeInfo1, fee.feeInfo2, fee.feeInfo3); return FEE_FLAG_FAIL; } bool CParamMan::GetOBUCardFee(OBUCardInfoHelper &infoHelper, CFeeCalcInfo &fee) { COBUFileEF04 EF04 = infoHelper.GetEF04Info(); if(GetOBUFee(VEH_CLASS_FEE, infoHelper.GetOBUVehType(), infoHelper.GetOBUAxleCount(), &EF04, fee) == FEE_FLAG_SUCC) { int CashTotal = Array2Int(EF04.PRO_TotalCash, 3); //累计应收金额 3 全程应收金额累计 int InCashTotal = Array2Int(EF04.PRO_TotalInCash, 3); //累计实收金额 3 全程实收金额累计 int InProvCashTotal = Array2Int(EF04.PRO_CashInProv, 3); //本省累计应收金额 3 ETC门架系统(含兼具门架功能的收费站入出口)根据OBU返回状态判断后累加写入应收金额,进入下一省后重新计数 int InProvInCashTotal = Array2Int(EF04.PRO_TotalInCashInProv, 3); //本省累计实收金额 3 ETC门架系统(含兼具门架功能的收费站入出口)根据OBU返回状态判断后累加写入,进入下一省后重新计数 fee.OutProvCashTotal = CashTotal - InProvCashTotal; //外省总应收 fee.OutProvInCashTotal = InCashTotal - InProvInCashTotal; //外省总实收 //fee.FeeMileAgeTotal = FeeMileage2; //收费总里程 //fee.ProvCashTotal = ProvCashTotal2; //本省应收 //fee.ProvInCashTotal = ProvInCashTotal2; //本省实收 //fee.ProvFeeMileAgeTotal = FeeMileage2; //本省收费里程 fee.TotalTransCount = Array2Int(EF04.PRO_TotalTransCount, 2); fee.InProvTransCount = EF04.PRO_TransCountInProv; fee.ProvCount = EF04.PRO_TotalProvCount; //累计通行省份个数 ETC门架系统(含兼具门架功能的收费站入出口)根据OBU返回状态判断后累加写入。入口置1出口清0 int gantryNo = Array2Int(EF04.PRO_InProvHex, 3); int ProvNo = GetProvNoFromGantryNo(gantryNo); if(ProvNo == 0) { ProvNo = BCD2Int(EF04.PRO_InAreaNo); } if(ProvNo != m_LocalAreaNo) //与当前省份编码不相同 { fee.ProvCount++; } fee.Cash = fee.OutProvCashTotal + fee.InProvCashTotal; fee.InCash = fee.OutProvInCashTotal + fee.InProvInCashTotal; fee.TransFee = fee.InCash; fee.ProvCountInCard = fee.ProvCount; //通行省份(费率模块计算出,后面不修改) fee.OutProvCashTotalInCard = fee.OutProvCashTotal; //外省累计应收金额(费率模块计算出,后面不修改) fee.OutProvInCashTotalInCard = fee.OutProvInCashTotal; //外省累计实收金额(费率模块计算出,后面不修改) fee.FeeMileAgeTotalInCard = fee.FeeMileAgeTotal; //本省计费里程(费率模块计算出,后面不修改) fee.InProvCashTotalInCard = fee.InProvCashTotal; //本省应收金额(费率模块计算出,后面不修改) fee.InProvInCashTotalInCard = fee.InProvInCashTotal; //本省实收金额 (费率模块计算出,后面不修改) fee.FeeMileAgeInCard = fee.FeeMileAge; //本次计费里程(费率模块计算出,后面不修改) return true; } return false; } //bool CParamMan::doGetOBUFee(OBUCardInfoHelper &infoHelper, int &VehSign, CFeeCalcInfo &fee, QString &FreeInfo, int &ErrorCode, QString &ErrorInfo) //{ // //不计费:军车,应急,内蒙警车(u转),路政(u转) // //int PayType = infoHelper.GetCardType(); //这里默认成用卡支付 // VehSign = infoHelper.GetAllFreeVehSign(FreeInfo); // if(VehSign != VEH_SIGN_FEE) // { // //不计费或者0计费 // CParamMan::InitFeeCalcInfo(fee, EXIT_FEE_TYPE_OBU, infoHelper.GetOBUVehType()); // return true; // }else{ // if(infoHelper.GetOBUCardFee(fee) == false) //feeSpecial // { // ErrorCode = ERROR_CODE_BASE_CALCFEE + 0x01; // ErrorInfo = QString("计费错误,错误代码:%1,特情代码:%2").arg(fee.FeeCalcResult).arg(fee.FeeSpecial); // return false; //计费失败 // } // } //} int CParamMan::GetOBUCardFeeInfo(OBUCardInfoHelper &infoHelper,const QString &enStationId, CFeeCalcInfo &obuFee, int &VehSign, int &ErrorCode, QString &ErrorInfo) { QString FreeInfo(""); VehSign = infoHelper.GetAllFreeVehSign(FreeInfo); if(VehSign != VEH_SIGN_FEE) { //不计费或者0计费 CParamMan::InitFeeCalcInfo(obuFee, EXIT_FEE_TYPE_OBU, infoHelper.GetOBUVehType()); return FEE_FLAG_SUCC; } //计费 if(GetOBUCardFee(infoHelper, obuFee) == false) { ErrorCode = ERROR_CODE_BASE_CALCFEE + 0x100; ErrorInfo = QString("OBU计费失败"); //tradeStateInfo.TRADESTATUS = 1; //tradeStateInfo.LOGICCAUSE = ErrorCode; //strncpy(tradeStateInfo.ErrorInfo, ErrorInfo.toUTF8().data(), sizeof(tradeStateInfo.ErrorInfo)-1); return -23; } CFeeCalcInfo minFee; QString exStationId = gLaneApp->GetStationId(); int CardType = infoHelper.GetCardType(); if(GetMinFee(enStationId, exStationId, m_LocalRoadNo, m_LocalStaNo, CardType, obuFee.FeeVehType, minFee) == false) { ErrorCode = ERROR_CODE_BASE_CALCFEE + 0x101; ErrorInfo = QString("最小费额查询失败"); //tradeStateInfo.TRADESTATUS = 1; //tradeStateInfo.LOGICCAUSE = ErrorCode; //strncpy(tradeStateInfo.ErrorInfo, ErrorInfo.toUtf8().data(), sizeof(tradeStateInfo.ErrorInfo)-1); return -24; } //最小费额判断 if(MinFeeCompare(minFee, CardType, obuFee, ErrorInfo) != 0) { ErrorCode = ERROR_CODE_BASE_CALCFEE + 0x102; //最小费额比较失败 //tradeStateInfo.TRADESTATUS = 1; //tradeStateInfo.LOGICCAUSE = ErrorCode; //strncpy(tradeStateInfo.ErrorInfo, ErrorInfo.toUtf8().data(), sizeof(tradeStateInfo.ErrorInfo)-1); return -25; } //这些应该都是卡内计费成功的 //抢险救灾 QString EmerCarId(""); QString DisCountInfo(""); QString BeginDate(""); QString EndDate(""); if(IsEmerCar(infoHelper.GetOBUVehId(true, false), EmerCarId, VehSign, DisCountInfo, BeginDate, EndDate)) { //免费 obuFee.InCash = 0; obuFee.TransFee = 0; FreeInfo = QString("优免车辆:%1,%2").arg(EmerCarId, DisCountInfo); return FEE_FLAG_SUCC; } //节假日 if(IsHoliday() && infoHelper.GetOBUVehType() == VEH_TYPE_1) { //免费 obuFee.InCash = 0; obuFee.TransFee = 0; VehSign = VEH_SIGN_HOLIDAY; FreeInfo = QString("节假日车辆:%1,%2").arg(infoHelper.GetOBUIdHex(), infoHelper.GetOBUVehId(true, true)); //gLaneApp->m_TransQueue.AddOrUpdateQueue(infoHelper.GetOBUIdHex(), fee); return FEE_FLAG_SUCC; //FEE_FLAG_ALLFREE; } //内蒙警车免内蒙,内蒙路政,30分钟u转 VehSign = infoHelper.GetProvFreeVehSign(FreeInfo); if(VehSign != VEH_SIGN_FEE) //免本省 { obuFee.InCash = obuFee.OutProvInCashTotal; obuFee.TransFee = infoHelper.GetTransFee(obuFee.InCash); return FEE_FLAG_SUCC; //FEE_FLAG_PROVFREE; } //正常计费 obuFee.Cash = obuFee.OutProvCashTotal + obuFee.InProvCashTotal; obuFee.InCash = obuFee.OutProvInCashTotal + obuFee.InProvInCashTotal; obuFee.TransFee = infoHelper.GetTransFee(obuFee.InCash); return FEE_FLAG_SUCC; //FEE_FLAG_SUCC; } int CParamMan::GetCPCFee(const int VehType, const int AxisCount, const CCPCDFEF01 &DF_EF01, const CCPCDFEF02 &DF_EF02, CFeeCalcInfo &fee) { InitFeeCalcInfo(fee); TradingInfo tradeInfo; memset(&tradeInfo, 0, sizeof(TradingInfo)); FeeInfo feeInfo; memset(&feeInfo, 0, sizeof(FeeInfo)); RoadInfo roadInfo; memset(&roadInfo, 0, sizeof(RoadInfo)); QString str = GetStationHex(m_LocalAreaNo, m_LocalRoadNo, m_LocalStaNo); strncpy(tradeInfo.curTollGantry, str.toUtf8().data(), sizeof(tradeInfo.curTollGantry)-1); //当前收费门架编码,当初始化函数中的当前门架编码为null时,应支持全省所有门架的费用查询(含代收);初始化函数中的当前门架编码不为null时,该字段与初始化函数中的当前门架编码相等。 str = QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm:ss"); strncpy(tradeInfo.curPassTime, str.toUtf8().data(), sizeof(tradeInfo.curPassTime)-1); //COBUFileEF04 *pEF04 = (COBUFileEF04 *)b3.EF04Info; tradeInfo.laneStatus = DF_EF01.CPC_InOutStatus; str = GetStationHex(BCD2Int(DF_EF01.CPC_InAreaNo), DF_EF01.CPC_InRoadNo, Array2Int(DF_EF01.CPC_InStationNo, 2)); strncpy(tradeInfo.enTollStationHex, str.toUtf8().data(), sizeof(tradeInfo.enTollStationHex)-1); str = Array2HexStr(DF_EF02.CPC_NewGantry, 3, false); strncpy(tradeInfo.lastGantryHex, str.toUtf8().data(), sizeof(tradeInfo.lastGantryHex)-1); tradeInfo.vehicleUserType = 0; //前面验证了标签和卡的usertype一致性 tradeInfo.tagType = 2; //这里先固定为CPC tradeInfo.axleCount = 0; //OBU轴数 tradeInfo.enAxleCount = AxisCount; tradeInfo.cardType = 0; tradeInfo.vehicleType = VehType; //OBU车型 tradeInfo.enVehicleType = 0; //入口车型 tradeInfo.vehicleClass = 0; //t.feeSumLocal = Array2Int(pEF04->PRO_TotalInCash, 3); tradeInfo.totalWeight = Array2Int(DF_EF01.CPC_InWeight, 4); //货车总重,单位:kg,差异化 tradeInfo.vehicleStatusFlag = 0xff; //车辆状态标识。 str = Array2HexStr(DF_EF02.CPC_FirstGantry, 3, false); strncpy(tradeInfo.feeProvBeginHex, str.toUtf8().data(), sizeof(tradeInfo.feeProvBeginHex)-1); // 本省入口ETC门架信息,(省界入口ETC门架或省内第一个ETC门架的6位HEX编码,收费站入口格式为“000000”) tradeInfo.feeProvMileage = Array2Int(DF_EF02.CPC_ProvMileage, 3); // ETC标签EF04文件或者CPC EF02文件中的本省累计计费里程,单位:M(米) tradeInfo.payFeeSumLocal = Array2Int(DF_EF02.CPC_ProvPayFee, 3); // ETC标签EF04文件中读出的本省累计应收金额,CPC卡EF02文件中读出的本省累计金额,单位:分 tradeInfo.realFeeSumLocal = tradeInfo.payFeeSumLocal; // ETC标签EF04文件中读出的本省累计实收金额,单位:分,默认填-1 表示此字段无效。 fee.FeeCalcResult = getStaFee(tradeInfo, feeInfo, nullptr, roadInfo, 0); if(fee.FeeCalcResult == 0 && strcmp(feeInfo.feeSpecial, "") == 0) { fee.ExitFeeType = EXIT_FEE_TYPE_CPC; fee.InProvCashTotal = feeInfo.feeSpare1; fee.InProvInCashTotal = feeInfo.feeSpare1; fee.FeeMileAgeTotal = feeInfo.feeSpare2; //计费里程是总里程吗?好像不能区分本省计费里程 fee.FeeMileAge = feeInfo.feeMileage; //本次计费里程 fee.FeeVehType = feeInfo.feeVehicleType; strncpy(fee.FeeSpecial, feeInfo.feeSpecial, sizeof(fee.FeeSpecial)-1); fee.TollFeeCheck = feeInfo.feeSpare1; //fee.FeeSpare1 = feeInfo.feeSpare1; fee.PayFee = feeInfo.payFee; fee.Fee = feeInfo.realFee; strncpy(fee.tollintervalid, feeInfo.tollIntervalIDs, sizeof(fee.tollintervalid)-1); //计费单元id strncpy(fee.payFeeGroup, feeInfo.payFeeGroup, sizeof(fee.payFeeGroup)-1); // 收费单元应收金额(优惠前金额)组合,单位:分,若有代收用"|"分隔。如:"1000|2000"表示按照tollIntervalIDs中先后出现的两个收费单元分别应收费(优惠前)10元和20元。 strncpy(fee.discountFeeGroup, feeInfo.discountFeeGroup, sizeof(fee.discountFeeGroup)-1); //收费单元优惠金额组合,单位:分,若有代收用"|"分隔。如:"200|700"表示按照tollIntervalIDs中先后出现的两个收费单元分别应优惠2元和7元。 strncpy(fee.feeGroup, feeInfo.feeGroup, sizeof(fee.feeGroup)-1); //交易金额(应收金额减去优惠金额)组合,单位:分,若有代收用"|"分隔。如:"800|1300"表示按照tollIntervalIDs中先后出现的两个收费单元交易金额分别为8元和13元。 strncpy(fee.feeInfo1, feeInfo.feeInfo1, sizeof(fee.feeInfo1)-1); //计费信息1,省份自定义,utf-8编码(若有汉字)计费模块可以使用自定义字段(计费信息1、2、3)返回优惠率、优惠类型及说明、错误码或特情等信息,该信息会在交易流水中上传省中心,用于省中心的自定义分析。推荐参照前面字段的样式。 strncpy(fee.feeInfo2, feeInfo.feeInfo2, sizeof(fee.feeInfo2)-1); //计费信息2,省份自定义,utf-8编码(若有汉字) strncpy(fee.feeInfo3, feeInfo.feeInfo3, sizeof(fee.feeInfo3)-1); WRITE_LOG("计费成功:feeInfo1=%s,feeInfo2=%s,feeInfo3=%s", fee.feeInfo1, fee.feeInfo2, fee.feeInfo3); return FEE_FLAG_SUCC; } WRITE_LOG("计费失败:calcResult=%d,feeInfo1=%s,feeInfo2=%s,feeInfo3=%s", fee.FeeCalcResult, fee.feeInfo1, fee.feeInfo2, fee.feeInfo3); return FEE_FLAG_FAIL; } #endif bool CParamMan::CheckPassword(const QString &Password,const QString &EncPassword) { if(Password.compare(EncPassword) == 0) { return true; }else{ return Password.compare(DeCrypt(EncPassword)) == 0; } } bool CParamMan::CheckUser(const QString &UserNo,const QString &Password,const int ManId1,int &ManId2, QString &UserName, int &GroupNo,const int RoadNo, const int StaNo) { QMutexLocker lock(&m_Mutex); int index = GetIndex(PFILE_ID_OPERATOR, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return false; } if((m_PFileInfo[index].pDBF == nullptr) || (m_PFileInfo[index].pDBF->IsOpened() == false)) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return false; } LibDBF *pDBF = m_PFileInfo[index].pDBF; for(int i=pDBF->First();i>=0;i=pDBF->Next()) { QString AUserNo; QString AUserName; QString APassword; qint64 AManId; qint64 AGroupNo; qint64 ARoadNo; qint64 AStaNo; pDBF->dbf_get("MANNO", AUserNo); pDBF->dbf_get("MAN", AUserName); pDBF->dbf_get("PASSWD", APassword); pDBF->dbf_get("MANID", AManId); pDBF->dbf_get("GROUPNO", AGroupNo); pDBF->dbf_get("ROADNO", ARoadNo); pDBF->dbf_get("STANO", AStaNo); if((ARoadNo == RoadNo || 0 == RoadNo) && (AStaNo == StaNo || 0 == StaNo) && (AUserNo == UserNo) && (AManId == ManId1 || AManId == ManId2) && CheckPassword(Password, APassword)) { UserName = AUserName; GroupNo = AGroupNo; ManId2 = AManId; return true; } } return false; } //用卡验证 bool CParamMan::CheckUser(const QString &UserNo, const uint CardId, const int ManId1, int &ManId2, QString &UserName, int &GroupNo, const int RoadNo, const int StaNo) { QMutexLocker lock(&m_Mutex); int index = GetIndex(PFILE_ID_OPERATOR, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return false; } if((m_PFileInfo[index].pDBF == nullptr) || (m_PFileInfo[index].pDBF->IsOpened() == false)) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return false; } LibDBF *pDBF = m_PFileInfo[index].pDBF; for(int i=pDBF->First();i>=0;i=pDBF->Next()) { QString AUserNo; QString AUserName; QString APassword; qint64 AManId; qint64 AGroupNo; qint64 ARoadNo; qint64 AStaNo; QString ACardIdHex; pDBF->dbf_get("MANNO", AUserNo); pDBF->dbf_get("MAN", AUserName); pDBF->dbf_get("PASSWD", APassword); pDBF->dbf_get("MANID", AManId); pDBF->dbf_get("GROUPNO", AGroupNo); pDBF->dbf_get("CARDID", ACardIdHex); pDBF->dbf_get("ROADNO", ARoadNo); pDBF->dbf_get("STANO", AStaNo); QString CardIdHex = Int2HexStr(CardId, 8); if((ARoadNo == RoadNo || 0 == RoadNo) && (AStaNo == StaNo || 0 == StaNo) && (AUserNo == UserNo) && (AManId == ManId1 || AManId == ManId2) && CardIdHex.compare(ACardIdHex, Qt::CaseInsensitive) == 0) { UserName = AUserName; GroupNo = AGroupNo; ManId2 = AManId; return true; } } return false; } void CParamMan::UpdateParamInfo(const uint PFileId, const int roadNo, const int staNo, const int ErrorCode, const QString &FileCName,const QString &NewBaseFileName, const QString &TempFileName) { QFile::setPermissions(TempFileName, QFileDevice::WriteOther); //清除只读标记 #ifdef PARAMMANAGER_LANE if(ErrorCode == 0) { //提示加载成功 //更新版本信息 QString strVersion = GetBaseInfo(PFileId, roadNo, staNo, 1); gLaneApp->ShowInfoParamVersion(PFileId, FileCName, strVersion); }else{ SHOWINFO(INFO_WARNING, QString("[%1]加载失败:%2").arg(FileCName).arg(ErrorCode)); } #endif } void ParamLoadCompleteCallBack(void *pSender, unsigned int iPFileId, int ErrorCode,const QString &TempFileName,const QString &NewBaseFileName) { #ifdef PARAMMANAGER_LANE gLaneApp->ParamDownNotify(MESSAGE_PARAM_BACKLOAD_COMPLETE, iPFileId, ErrorCode, NewBaseFileName); #endif } //后台加载 bool CParamMan::LoadParamBackground(CPFileInfo &fileInfo, const QString &srcFileName, const QString &dstFileName) { if(fileInfo.LoadType == PFILE_LOADTYPE_HASH) { return HASH_LoadListBack(fileInfo.hHash, dstFileName, srcFileName, ParamLoadCompleteCallBack, this) == 0; }else{ SHOWINFO(INFO_ERROR, QString("参数[%1]不支持实时加载").arg(fileInfo.PFileCName)); return false; } } //iDownResult=1:下载成功,-1:MD5校验失败,-2:连接下载服务器失败,-3解压失败,0:下载失败(其他原因) bool CParamMan::OnParamDownLoadComplete(const uint FileId,const QString &ParamFileName, const int iDownResult, const bool bUpdateAll) { if(iDownResult != 1) { SHOWINFO(INFO_NORMAL, QString("参数下载失败%1").arg(ParamFileName)); return false; } QMutexLocker lock(&m_Mutex); bool bMatched = false; for(int i=0;i 0 && indexDot > 0) { PFileName = PFileName.mid(0, indexUnder) + PFileName.mid(indexDot); } for(int i=0;iIsOpened() == false)) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return false; } LibDBF *pDBF = m_PFileInfo[index].pDBF; for(int i=pDBF->First();i>=0;i=pDBF->Next()) { QString StartTime; QString OverTime; pDBF->dbf_get("STARTTIME", StartTime); pDBF->dbf_get("OVERTIME", OverTime); QDateTime startDT = Str2DateTime(StartTime); QDateTime overDT = Str2DateTime(OverTime); QDateTime DT = QDateTime::currentDateTime(); if(DT >= startDT && DT<= overDT) { return true; } } return false; } #ifdef PARAMMANAGER_LANE void CParamMan::InitFeeCalcInfo(CFeeCalcInfo &feeCalcInfo, const int ExitFeeType, const int FeeVehType) { memset(&feeCalcInfo, 0, sizeof(CFeeCalcInfo)); //feeCalcInfo.idx = GetIDX().toInt(); //feeCalcInfo.FeeFlag = FeeFlag; //计费标识 feeCalcInfo.ExitFeeType = ExitFeeType; //计费方式 //feeCalcInfo.VehSign = VehSign; //免费标识 //feeCalcInfo.VehKind = VehKind; //feeCalcInfo.Flag = Flag; //feeCalcInfo.PayType = PayType; //feeCalcInfo.bTruckFeeConfirmed = false; feeCalcInfo.Cash = 0; //应收金额 feeCalcInfo.InCash = 0; //实收金额 feeCalcInfo.TransFee = 0; //实际扣费金额(卡面扣款金额) feeCalcInfo.FeeCalcResult = FEE_CALC_RESULT_UNKNOWN; //是否计费成功(计费模块) feeCalcInfo.FeeSpecial[0] = '0'; //计费特情 feeCalcInfo.FeeVehType = FeeVehType; feeCalcInfo.ProvCount = 0; //通行省份 feeCalcInfo.OutProvCashTotal = 0; //外省累计应收金额 feeCalcInfo.OutProvInCashTotal = 0; //外省累计实收金额 feeCalcInfo.FeeMileAgeTotal = 0; //计费里程 feeCalcInfo.InProvCashTotal = 0; //本省应收金额 feeCalcInfo.InProvInCashTotal = 0; //本省实收金额 feeCalcInfo.FeeMileAge = 0; //本省计费里程 //feeCalcInfo.feeProvBeginHex[0] = '0'; //feeCalcInfo.feeProvBeginTime[0] = '0'; //feeCalcInfo.splitProv[0] = '0'; //分省信息 //feeinfo //feeCalcInfo.tollIntervalsCount = 0; feeCalcInfo.tollintervalid[0] = '0'; //计费单元id feeCalcInfo.payFeeGroup[0] = '0'; // 收费单元应收金额(优惠前金额)组合,单位:分,若有代收用"|"分隔。如:"1000|2000"表示按照tollIntervalIDs中先后出现的两个收费单元分别应收费(优惠前)10元和20元。 feeCalcInfo.discountFeeGroup[0] = '0'; //收费单元优惠金额组合,单位:分,若有代收用"|"分隔。如:"200|700"表示按照tollIntervalIDs中先后出现的两个收费单元分别应优惠2元和7元。 feeCalcInfo.feeGroup[0] = '0'; //交易金额(应收金额减去优惠金额)组合,单位:分,若有代收用"|"分隔。如:"800|1300"表示按照tollIntervalIDs中先后出现的两个收费单元交易金额分别为8元和13元。 feeCalcInfo.feeInfo1[0] = '0'; //计费信息1,省份自定义,utf-8编码(若有汉字)计费模块可以使用自定义字段(计费信息1、2、3)返回优惠率、优惠类型及说明、错误码或特情等信息,该信息会在交易流水中上传省中心,用于省中心的自定义分析。推荐参照前面字段的样式。 feeCalcInfo.feeInfo2[0] = '0'; //计费信息2,省份自定义,utf-8编码(若有汉字) feeCalcInfo.feeInfo3[0] = '0'; feeCalcInfo.FeeBoadPlay = 0; //第二种情况 :在线计费 //feeCalcInfo.TollFeeQuery = 0; //feeCalcInfo.TollIntervalsCountQuery = 0; //feeCalcInfo.TollIntervalsGroupQuery[0] = '0'; //feeCalcInfo.TransTimeGroupQuery[0] = '0'; //feeCalcInfo.ChargePayGroupQuery[0] = '0'; //feeCalcInfo.ChargeFeeGroupQuery[0] = '0'; //feeCalcInfo.ChargeDiscountGroupQuery[0] = '0'; //feeCalcInfo.RateVersionQroupQuery[0] = '0'; //feeCalcInfo.PayListNo[0] = '0'; //支付流水号 //feeCalcInfo.PayCode[0] = '0'; //支付码 feeCalcInfo.FeeQueryResult = 0; } #endif bool CParamMan::GetMinFee(const QString &enID, const QString &exID, const int roadNo, const int staNo,const int CardType,const int VehType,int &MinFee, int &MinFee95, int &MinFeeMileAge, QString &MinFeeVer, QString &provFeeInfo, int &ProvCount,int &OutProvCashTotal,int &OutProvInCashTotal,int &InProvCashTotal,int &InProvInCashTotal,int &InProvMileAge) { QMutexLocker lock(&m_Mutex); int index = GetIndex(PFILE_ID_MINPATHFEE, roadNo, staNo); if(index < 0) { return false; } if(m_PFileInfo[index].pQrySQLite == nullptr) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return false; } QString sql = QString("select feeinfo,version from %1 where enId='%2' and exId='%3' LIMIT 1").arg(m_PFileInfo[index].HashKeyFieldName, enID, exID); //LibDBF *pDBF = m_PFileInfo[index].pDBSQLite; if(m_PFileInfo[index].pQrySQLite->exec(sql) && m_PFileInfo[index].pQrySQLite->next()) { MinFeeVer = m_PFileInfo[index].pQrySQLite->value(1).toString(); QString strVehType = QString::number(VehType); QString feeInfo = m_PFileInfo[index].pQrySQLite->value(0).toString(); QJsonDocument doc = QJsonDocument::fromJson(feeInfo.toUtf8(), nullptr); QJsonArray arr = doc.array(); for (int i = 0; i < arr.count(); i++) { QJsonObject obj = arr[i].toObject(); if((obj["vType"].toString() == strVehType)) { MinFee = obj["fee"].toString().toInt(); MinFee95 = obj["fee95"].toString().toInt(); MinFeeMileAge = obj["m"].toString().toInt(); QJsonArray arrProvFeeInfo = obj["provFeeInfo"].toArray(); provFeeInfo = QString(QJsonDocument(arrProvFeeInfo).toJson(QJsonDocument::Compact)); ProvCount = 0; OutProvCashTotal = 0; OutProvInCashTotal = 0; InProvCashTotal = 0; InProvInCashTotal = 0; InProvMileAge = 0; QString pFeeName("pFee"); if(CardType == CARD_TYPE_STORE || CardType == CARD_TYPE_TOLLY) { pFeeName = QString("pFee95"); } QJsonObject objProvFee; for(int i = 0;iexec(sql) && m_PFileInfo[index].pQrySQLite->next()) { QString strVehType = QString::number(VehType); QString feeInfo = m_PFileInfo[index].pQrySQLite->value(0).toString(); QJsonDocument doc = QJsonDocument::fromJson(feeInfo.toUtf8(), nullptr); QJsonArray arr = doc.array(); for (int i = 0; i < arr.count(); i++) { QJsonObject obj = arr[i].toObject(); if((obj["vType"].toString() == strVehType)) { //fee.FeeFlag = FEE_FLAG_SUCC; fee.FeeVehType = VehType; fee.MinFee = obj["fee"].toString().toInt(); fee.MinFee95 = obj["fee95"].toString().toInt(); fee.MinFeeMileAge = obj["m"].toString().toInt(); QString minFeeVer = m_PFileInfo[index].pQrySQLite->value(1).toString(); WRITE_LOG("MINFeeVer=%s", minFeeVer.toUtf8().data()); strncpy(fee.MinFeeVer, minFeeVer.toUtf8().data(), sizeof(fee.MinFeeVer)-1); //最小费额版本 utf8编码 fee.ExitFeeType = EXIT_FEE_TYPE_MINFEE; fee.Cash = fee.MinFee; if(CardType == CARD_TYPE_STORE || CardType == CARD_TYPE_TOLLY) { fee.InCash = fee.MinFee95; fee.TransFee = fee.MinFee95; //实际扣费金额(卡面扣款金额) }else{ fee.InCash = fee.MinFee; fee.TransFee = fee.MinFee; //实际扣费金额(卡面扣款金额) } fee.FeeRate = 1000; QJsonArray arrProvFeeInfo = obj["provFeeInfo"].toArray(); //QString splitFee = QString(QJsonDocument(arrProvFeeInfo).toJson(QJsonDocument::Compact)); //strcpy(fee.splitFeeMinFee, splitFee.toUtf8().data()); fee.ProvCount = 0; fee.OutProvCashTotal = 0; fee.OutProvInCashTotal = 0; fee.InProvCashTotal = 0; fee.InProvInCashTotal = 0; fee.FeeMileAgeTotal = fee.MinFeeMileAge; fee.FeeMileAge = 0; QString pFeeName("pFee"); if(CardType == CARD_TYPE_STORE || CardType == CARD_TYPE_TOLLY) { pFeeName = QString("pFee95"); } QString splitFeeAll; //= QString("{\"provinceFees\":["); QString splitFee; QJsonObject objProvFee; int splitCash = 0; int splitInCash = 0; QString feeGroup; QString payFeeGroup; QString intervalsGroup; QString discountFeeGroup; QString mVerGroup; QString pVerGroup; int intervalsCount; QString provId; for(int i = 0;iIsOpened() == false)) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return false; } LibDBF *pDBF = m_PFileInfo[index].pDBF; if(pDBF->First() == 0) { qint64 iValue = 0; if(pDBF->dbf_get("MINETCRATE", iValue) >= 0) { m_LaneOpt.MinETCRate = iValue; } if(pDBF->dbf_get("MAXETCRATE", iValue) >= 0) { m_LaneOpt.MaxETCRate = iValue; } if(pDBF->dbf_get("MINCPCRATE", iValue) >= 0) { m_LaneOpt.MinCPCRate = iValue; } if(pDBF->dbf_get("MAXCPCRATE", iValue) >= 0) { m_LaneOpt.MaxCPCRate = iValue; } if(pDBF->dbf_get("MAXHCRATE", iValue) >= 0) { m_LaneOpt.MaxHCRate = iValue; } if(pDBF->dbf_get("MAXONLINE", iValue) >= 0) { m_LaneOpt.MaxOnLineRate = iValue; } if(pDBF->dbf_get("MAXHCONLIN", iValue) >= 0) { m_LaneOpt.MaxHCOnLineRate = iValue; } } } return true; } bool CParamMan::CheckMinFee(const int MinFee, const int Cash,const int ExitFeeType,const int VehType, const int CardType, int &ErrorCode, QString &ErrorInfo) { ReadLaneParam(); //读取费额比例参数 if(MinFee <= 0) { ErrorCode = ERROR_CODE_BASE_CALCFEE + 0x20; ErrorInfo = QString("最小费额(%1)异常").arg(QString::number(MinFee/100.0, 'f', 2)); return false; } QString ExitFeeTypeName = GetExitFeeTypeName(ExitFeeType); int rate = ((double)Cash / (double)MinFee)*1000; //bool bCheckResult = false; int MinRate = 0; int MaxRate = 999999; switch(ExitFeeType) { case EXIT_FEE_TYPE_OBU: MinRate = m_LaneOpt.MinETCRate; if(IsTruck(VehType)) { MaxRate = m_LaneOpt.MaxHCRate; }else{ MaxRate = m_LaneOpt.MaxETCRate; } break; case EXIT_FEE_TYPE_CPC: MinRate = m_LaneOpt.MinCPCRate; if(IsTruck(VehType)) { MaxRate = m_LaneOpt.MaxHCRate; }else{ MaxRate = m_LaneOpt.MaxCPCRate; } break; case EXIT_FEE_TYPE_PROV: case EXIT_FEE_TYPE_MINISTRY: if(CardType == CARD_TYPE_PASS) { MinRate = m_LaneOpt.MinCPCRate; }else{ MinRate = m_LaneOpt.MinETCRate; } if(IsTruck(VehType)) { MaxRate = m_LaneOpt.MaxHCOnLineRate; }else{ MaxRate = m_LaneOpt.MaxOnLineRate; } break; } if(rate < MinRate) { ErrorCode = ERROR_CODE_BASE_CALCFEE + 0x22; //比例小 ErrorInfo = QString("%1金额(%2)/最小费额(%3)比例%4%小于%5%").arg(ExitFeeTypeName, QString::number(Cash/100.0, 'f', 2), QString::number(MinFee/100.0, 'f', 2), QString::number(rate/10.0, 'f', 2), QString::number(m_LaneOpt.MaxHCOnLineRate/10.0, 'f', 2)); return false; } if(rate > MaxRate) { ErrorCode = ERROR_CODE_BASE_CALCFEE + 0x23; //比例大 ErrorInfo = QString("%1金额(%2)/最小费额(%3)比例%4%大于%5%").arg(ExitFeeTypeName, QString::number(Cash/100.0, 'f', 2), QString::number(MinFee/100.0, 'f', 2), QString::number(rate/10.0, 'f', 2), QString::number(m_LaneOpt.MaxHCOnLineRate/10.0, 'f', 2)); return false; } ErrorCode = 0; ErrorInfo = QString("最小费额比正常"); return true; } int CParamMan::GetDiscount(const QString &CardIssuer,const int CardUType,const int CardType) { QMutexLocker lock(&m_Mutex); int index = GetIndex(PFILE_ID_DISCOUNT, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return 1000; } if((m_PFileInfo[index].pDBF == nullptr) || (m_PFileInfo[index].pDBF->IsOpened() == false)) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return 1000; } LibDBF *pDBF = m_PFileInfo[index].pDBF; for(int i=pDBF->First();i>=0;i=pDBF->Next()) { QString ACardIssuer; qint64 ACardUType; qint64 ACardType; qint64 ADiscount; pDBF->dbf_get("DISTYPE", ACardType); //卡类型 pDBF->dbf_get("NETNO", ACardIssuer); //发行方 pDBF->dbf_get("CARDUTYPE", ACardUType); //卡用户类型 pDBF->dbf_get("DIS", ADiscount); //三个条件都满足 if((CardIssuer == ACardIssuer) && (CardUType == ACardUType) && (CardType == ACardType) && (ACardIssuer.compare("0") != 0) && (ACardUType != 0) && (ACardType != 0)) { return ADiscount; } //内蒙警车:发行方,卡用户类型 if((CardIssuer == ACardIssuer) && (CardUType == ACardUType) && (ACardIssuer.compare("0")!= 0) && (ACardUType != 0) && (ACardType== 0)) { return ADiscount; } //普通etc卡:卡类型,卡用户类型=0 if((CardType == ACardType) && (CardUType == ACardUType) && (ACardIssuer.compare("0")== 0) && (ACardType != 0) && (ACardUType == 0)) { return ADiscount; } //应急车:卡用户类型=26 if((CardUType == ACardUType) && (ACardIssuer.compare("0")== 0) && (CardUType != 0) && (ACardType == 0)) { return ADiscount; } //etc卡,卡类型 if((CardType == ACardType) && (ACardIssuer.compare("0")== 0) && (CardUType == -1) && (ACardType != 0)) { return ADiscount; } } return 1000; //默认没有优惠; } //返回值:1=是行政车 0=是行政车但是过期 -1=不是行政车 int CParamMan::GetAdminInfo(const QString &VehPlateAll, QString &info, QString &begDT, QString &endDT) { QMutexLocker lock(&m_Mutex); //QString BegDT; //QString EndDT; QString ACarNo; QString Color; //QString Describ; QString VehPlate = ExtractPlate(VehPlateAll); QString VehPlateColor = ExtractPlateColorName(VehPlateAll); int index = GetIndex(PFILE_ID_ADMIN, m_LocalRoadNo, m_LocalStaNo); if(index < 0) { return -1001; } if((m_PFileInfo[index].pDBF == nullptr) || (m_PFileInfo[index].pDBF->IsOpened() == false)) { WRITE_LOG("参数表[%s]未打开:RoadNo=%d,StaNo=%d", m_PFileInfo[index].PFileCName.toUtf8().data(), m_PFileInfo[index].RoadNo, m_PFileInfo[index].StaNo); return -1002; } LibDBF *pDBF = m_PFileInfo[index].pDBF; for(int i=pDBF->First();i>=0;i=pDBF->Next()) { pDBF->dbf_get("ACARNO", ACarNo); pDBF->dbf_get("COLOR", Color); if(ACarNo.compare(VehPlate) == 0 && Color.compare(VehPlateColor) == 0) { pDBF->dbf_get("BEGDT", begDT); pDBF->dbf_get("ENDDT", endDT); pDBF->dbf_get("DESCRIB", info); QDateTime startDT = Str2DateTime(begDT); QDateTime overDT = Str2DateTime(endDT); QDateTime DT = QDateTime::currentDateTime(); if(DT >= startDT && DT<= overDT) { return 1; }else{ return 0; } } } return -1003; } #ifdef PARAMMANAGER_LANE void CParamMan::customEvent(QEvent *e) { if (e->type() == EVENT_LANEAPP_EVENT) //捕获消息 { CCommonEvent *p = (CCommonEvent *)e; switch(p->Msg) { case MESSAGE_PARAM_DOWNLOAD_COMPLETE: //MESSAGE_PARAM_DOWNLOAD_COMPLETE, FileId, iDownResult, ParamFileName OnParamDownLoadComplete(p->wParam, p->info, p->lParam, false); break; case MESSAGE_PARAM_BACKLOAD_COMPLETE: //MESSAGE_PARAM_BACKLOAD_COMPLETE, iPFileId, ErrorCode, NewBaseFileName OnParamLoadBackComplete(p->wParam, p->info, p->lParam); break; } } QObject::customEvent(e); } #endif