You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3422 lines
127 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "ParamManager.h"
#include "WriteLog.h"
#include "DBFHashList2.h"
#include <QSqlQuery>
#include <QVariant>
#include <QSqlError>
#include <QTextCodec>
#include <QSettings>
#include <QDebug>
#include "CommonFunc.h"
#include <QMutexLocker>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonParseError>
#include <QFileInfo>
#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;i<m_PFileInfo.size();i++)
{
if((m_PFileInfo[i].PFileId == PFileId) && (m_PFileInfo[i].RoadNo == roadNo) && (m_PFileInfo[i].StaNo == staNo))
return i;
}
WRITE_LOG("参数表未找到:PFILEID=%d,RoadNo=%d,StaNo=%d", PFileId, roadNo, staNo);
return -1;
}
qint64 CParamMan::GetFileGenTime(const QString &PFileName)
{
QFileInfo info(PFileName);
if(info.exists() && info.isFile())
{
return info.lastModified().toMSecsSinceEpoch();
}
return 0;
}
//卸载参数表
bool CParamMan::UnLoadParam(CPFileInfo &fileInfo)
{
switch(fileInfo.LoadType)
{
case PFILE_LOADTYPE_DBF :
return UnLoadDBF(fileInfo);
break;
#ifdef PARAMMANAGER_LANE
case PFILE_LOADTYPE_FEE :
return UnLoadFee(fileInfo);
#endif
break;
case PFILE_LOADTYPE_HASH :
return UnLoadHash(fileInfo);
break;
case PFILE_LOADTYPE_INI :
return UnLoadIni(fileInfo);
break;
case PFILE_LOADTYPE_SQB :
return UnLoadSQB(fileInfo);
break;
}
return false;
}
bool CParamMan::LoadParam(CPFileInfo &fileInfo)
{
QString LoadFileName = fileInfo.PFileName;
bool retValue = false;
switch(fileInfo.LoadType)
{
case PFILE_LOADTYPE_DBF :
retValue = LoadDBF(fileInfo);
break;
#ifdef PARAMMANAGER_LANE
case PFILE_LOADTYPE_FEE :
retValue = LoadFee(fileInfo);
break;
#endif
case PFILE_LOADTYPE_HASH :
retValue = LoadHash(fileInfo, LoadFileName);
break;
case PFILE_LOADTYPE_INI :
retValue = LoadIni(fileInfo);
break;
case PFILE_LOADTYPE_SQB :
retValue = LoadSQB(fileInfo);
break;
}
if(retValue)
{
int recordCount = GetRecordCount(fileInfo.PFileId, fileInfo.RoadNo, fileInfo.StaNo);
QString strVersion = GetBaseInfo(fileInfo.PFileId, fileInfo.RoadNo, fileInfo.StaNo, 1);
fileInfo.PFileGenTime = GetFileGenTime(m_LibBasePath + fileInfo.PFileName);
WRITE_LOG("[加载参数文件]成功:%s,%s,记录数=%d,Ver=%s", fileInfo.PFileCName.toUtf8().data(),
LoadFileName.toUtf8().data(),recordCount, strVersion.toUtf8().data());
return true;
}else{
QString FileName = m_LibBasePath + LoadFileName;
WRITE_LOG("[加载参数文件]失败:%s,%s", fileInfo.PFileCName.toUtf8().data(), FileName.toUtf8().data());
return false;
}
}
bool CParamMan::InitPFileInfo(const int LocalAreaNo, const int LocalRoadNo, const int LocalStaNo, const QString &InitStaInfo)
{
if(InitStaInfo.isEmpty())
{
m_LocalAreaNo = LocalAreaNo;
m_LocalRoadNo = LocalRoadNo;
m_LocalStaNo = LocalStaNo;
//车道最小费率
m_PFileMinFeeInfo.RoadNo = LocalRoadNo;
m_PFileMinFeeInfo.StaNo = LocalStaNo;
m_PFileInfo.push_back(m_PFileMinFeeInfo);
}else{
//智慧云最小费额
QJsonObject obj;
QJsonParseError je;
QJsonDocument doc = QJsonDocument::fromJson(InitStaInfo.toUtf8(), &je);
if(je.error == QJsonParseError::NoError && doc.isArray())
{
QJsonArray arr = doc.array();
for(int i=0;i<arr.size();i++)
{
CPFileInfo MinFeeInfo = m_PFileMinFeeInfo;
QJsonArray arr2 = arr.at(i).toArray();
MinFeeInfo.RoadNo = arr2[0].toInt();
MinFeeInfo.StaNo = arr2[1].toInt();
if(m_LocalAreaNo == 0 || m_LocalRoadNo == 0 || m_LocalStaNo == 0)
{
m_LocalAreaNo = LocalAreaNo;
m_LocalRoadNo = MinFeeInfo.RoadNo;
m_LocalStaNo = MinFeeInfo.StaNo;
}
MinFeeInfo.PFileName = QString("ALLROADMINFEE#%1#%2.SQB").arg(MinFeeInfo.RoadNo).arg(MinFeeInfo.StaNo);
m_PFileInfo.push_back(MinFeeInfo);
}
}else{
WRITE_LOG("初始化参数数组错误解析JSON错误%s", InitStaInfo.toUtf8().data());
return false;
}
}
for(int i=0;i<PFILE_INIT_COUNT;i++)
{
m_PFileInitInfo[i].RoadNo = m_LocalRoadNo;
m_PFileInitInfo[i].StaNo = m_LocalStaNo;
m_PFileInfo.push_back(m_PFileInitInfo[i]);
}
return true;
}
#ifndef PARAMMANAGER_LANE
bool CParamMan::CheckLoadMode(const int &LoadMode, const int PFileId)
{
return !(LoadMode == LOAD_MODE_OPEN || PFileId == PFILE_ID_ROADPRICE);
}
#endif
bool CParamMan::OpenParam(void *pSplash, QString &failFileName, const int LocalAreaNo, const int LocalRoadNo, const int LocalStaNo, const QString &InitStaInfo, const QString &libBasePath, const QString &libTempPath)
{
QMutexLocker lock(&m_Mutex);
m_LibBasePath = libBasePath;
m_LibTempPath = libTempPath;
if(!InitPFileInfo(LocalAreaNo, LocalRoadNo, LocalStaNo, InitStaInfo))
{
return false;
}
for(int i=0;i<m_PFileInfo.size();i++)
{
if(CHECKLOADMODE(m_PFileInfo[i].LoadMode, m_PFileInfo[i].PFileId) != true)
{
WRITE_LOG("[加载参数文件]%s(未加载)" , m_PFileInfo[i].PFileCName.toUtf8().data());
continue;
}
#ifdef PARAMMANAGER_LANE
failFileName = QString("文件:%1(%2)").arg(m_PFileInfo[i].PFileCName, m_PFileInfo[i].PFileName);
((QSplashScreen *)pSplash)->showMessage("加载(" + 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;i<m_PFileInfo.size();i++)
{
//qDebug()<<"[卸载参数文件]"<<m_PFileInfo[i].PFileCName;
WRITE_LOG("[卸载参数文件]%s", m_PFileInfo[i].PFileCName.toUtf8().data());
UnLoadParam(m_PFileInfo[i]);
}
}
bool CParamMan::LoadDBF(CPFileInfo &PFileInfo)
{
//UnLoadDBF(PFileInfo);
PFileInfo.pDBF = new LibDBF();
QString tbName = m_LibBasePath + PFileInfo.PFileName;
if(!PFileInfo.pDBF->Open(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<CBlackItem> vBlackInc;
if(GetBlackIncStatus(dtAllVer, resultInc, "CREATETIME", "STATUS", "BACKUP1", vBlackInc) > 0)
{
std::sort(vBlackInc.begin(), vBlackInc.end(), myfunction);
for(int i=0;i<vBlackInc.size();i++)
{
CBlackItem item = vBlackInc.at(i);
if(item.State == 1)
{
//进入黑名单
statusAll |= item.Status;
}else{
//解除黑名单
statusAll &= (~item.Status);
}
}
}
return statusAll;
}
int CParamMan::GetBlackIncStatus(const qint64 &dtAllVer, const QString &resultStr, const QString &fnCreateTime, const QString &fnStatus, const QString &fnState, vector<CBlackItem> &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<ja.count();i++)
{
QJsonObject objStatus= ja.at(i).toObject();
qint64 dtCreateTime = QDateTime::fromString(objStatus[fnCreateTime].toString(), "yyyy-MM-dd hh:mm:ss").toMSecsSinceEpoch();
if(dtCreateTime >= 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<lstReason.length();i++)
{
if(strReasonInfo.isEmpty())
{
strReasonInfo = GetSNReasonText(lstReason.at(i));
}else{
strReasonInfo += "," + GetSNReasonText(lstReason.at(i));
}
}
}else{
WRITE_LOG("DATA数组为空,JsonStr=%s", resultStr.toUtf8().data());
}
}else{
WRITE_LOG("JSON解析失败,JsonStr=%s", resultStr.toUtf8().data());
}
if(strReasonInfo.isEmpty())
{
strReasonInfo = QString("未知原因");
}
return strReasonInfo;
}
//返回值1-进入追缴2-解除追缴
int CParamMan::GtSNIncReason(const QString &resultStr, const QString &fnCreateTime, const QString &fnReason, const QString &fnState, const QString &fnOWEFee, QString &ErrorInfo)
{
qint64 dtMax = 0;
int iState = 0;
int iOWEFee = 0;
QString strReason;
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();
for(int i=0;i<ja.count();i++)
{
QJsonObject objStatus= ja.at(0).toObject();
qint64 dtCreateTime = QDateTime::fromString(objStatus[fnCreateTime].toString(), "yyyy-MM-dd hh:mmss").toMSecsSinceEpoch();
if(dtCreateTime > 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<lstReason.length();i++)
{
if(strReasonInfo.isEmpty())
{
strReasonInfo = GetSNReasonText(lstReason.at(i));
}else{
strReasonInfo += "," + GetSNReasonText(lstReason.at(i));
}
}
ErrorInfo = QString("追缴金额:%1,原因:%2").arg(iOWEFee).arg(strReasonInfo);
}else{
WRITE_LOG("JSON解析失败,JsonStr=%s", resultStr.toUtf8().data());
}
return iState;
}
//获取全量增量状态 追缴
bool CParamMan::GetSNAllInc(const int PFileIdAll, const int PFileIdInc,const QString &VehicleId, QString &ErrorInfo)
{
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, 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<int> updateIdList;
for(int i=0;i<m_PFileInfo.size();i++)
{
QString srcFileName = m_LibTempPath + m_PFileInfo[i].PFileName;
QString dstFileName = m_LibBasePath + m_PFileInfo[i].PFileName;
QString FileCName = m_PFileInfo[i].PFileCName;
if(CheckTempParamValid(m_PFileInfo[i], srcFileName, dstFileName, false) == 1)
{
UpdateParam(m_PFileInfo[i], FileCName, dstFileName, srcFileName);
}
}
}
#ifdef PARAMMANAGER_LANE
QString CParamMan::GetIDX()
{
QMutexLocker lock(&m_Mutex);
if(gLaneApp->m_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下载成功-1MD5校验失败-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<m_PFileInfo.size();i++)
{
//采用文件名称对比FileId和本应用中的PFileId没有对应关系
//含路段编码站编码文件名称
//WRITE_LOG("PFIle[%d] PFileName=%s", i, m_PFileInfo[i].PFileName.toUtf8().data());
if(ParamFileName.compare(m_PFileInfo[i].PFileName, Qt::CaseInsensitive) == 0)
{
bMatched = true;
SHOWINFO(INFO_NORMAL, QString("接收参数[%1],状态=%2").arg(m_PFileInfo[i].PFileCName).arg(iDownResult));
QString srcFileName = m_LibTempPath + m_PFileInfo[i].PFileName;
QString dstFileName = m_LibBasePath + m_PFileInfo[i].PFileName;
if(m_PFileInfo[i].IsRealUpdate || bUpdateAll)
{
return UpdateParam(m_PFileInfo[i], m_PFileInfo[i].PFileCName, dstFileName, srcFileName);
}
}
}
if(!bMatched)
{
WRITE_LOG("参数列表未匹配到文件信息:%s", ParamFileName.toUtf8().data());
}
return false;
//qDebug()<<"处理参数完成";
}
void CParamMan::OnParamLoadBackComplete(const uint FileId,const QString &NewBaseFileName, const int iLoadResult)
{
if(iLoadResult != 0)
{
SHOWINFO(INFO_WARNING, QString("后台参数加载失败:ErrorCode=%1,FileName=%2").arg(iLoadResult).arg(NewBaseFileName));
return;
}
QMutexLocker lock(&m_Mutex);
bool bMatched = false;
QString PFileName = ExtractFileName(NewBaseFileName);
int indexUnder = PFileName.lastIndexOf('_');
int indexDot = PFileName.lastIndexOf('.');
if(indexUnder > 0 && indexDot > 0)
{
PFileName = PFileName.mid(0, indexUnder) + PFileName.mid(indexDot);
}
for(int i=0;i<m_PFileInfo.size();i++)
{
if(m_PFileInfo[i].PFileName.compare(PFileName, Qt::CaseInsensitive) == 0)
{
bMatched = true;
QString FileCName = m_PFileInfo[i].PFileCName;
HANDLE h = m_PFileInfo[i].hHash;
QString TempFileName = m_LibTempPath + m_PFileInfo[i].PFileName;
if((iLoadResult == 0) && (h != INVALID_HANDLE_VALUE))
{
if(HASH_BackOnline(h, NewBaseFileName) == 0)
{
QString BasePath = ExtractFilePath(NewBaseFileName);
QSettings settings(m_LibBasePath + QString("DBFHASHLIST.INI"), QSettings::IniFormat);
settings.beginGroup("DBFHASHLIST");
settings.setValue(QString("BLACK_%1").arg(FileId), ExtractFileName(NewBaseFileName));
settings.endGroup();
}
}
UpdateParamInfo(m_PFileInfo[i].PFileId, m_PFileInfo[i].RoadNo, m_PFileInfo[i].StaNo, iLoadResult, FileCName, NewBaseFileName, TempFileName);
return;
}
}
if(!bMatched)
{
WRITE_LOG("参数列表未匹配到文件信息:%s", NewBaseFileName.toUtf8().data());
}
}
QString CParamMan::GetParamsStatus()
{
QMutexLocker lock(&m_Mutex);
QString StatusText;
for(int i=0;i<m_PFileInfo.size();i++)
{
QString strStatus;
if(CHECKLOADMODE(m_PFileInfo[i].LoadMode, m_PFileInfo[i].PFileId))
{
//InfoType=1获取版本号InfoType=2获取启用日期
int RecordCount = GetRecordCount(m_PFileInfo[i].PFileId, m_PFileInfo[i].RoadNo, m_PFileInfo[i].StaNo);
QString strVersion = GetBaseInfo(m_PFileInfo[i].PFileId, m_PFileInfo[i].RoadNo, m_PFileInfo[i].StaNo, 1);
strStatus = "{\"PFILEID\":" + QString::number(m_PFileInfo[i].PFileId) + ",\"PFILECNAME\":\"" +
m_PFileInfo[i].PFileCName + "\",\"VERSION\":\"" + strVersion + "\",\"COUNT\":\"" + QString::number(RecordCount) + "\"}";
if(StatusText.isEmpty())
{
StatusText = strStatus;
}else{
StatusText += "," + strStatus;
}
}
}
return "[" + StatusText + "]";
}
QString CParamMan::GetVerInfo()
{
#ifdef PARAMMANAGER_LANE
return QString("%1-%2-%3-%4-%5-%6-%7-%8-%9-%10-%11-%12-%13")
.arg(GetIDX(), GetBaseInfo(PFILE_ID_BASICINFO,m_LocalRoadNo, m_LocalStaNo, 1),GetBaseInfo(PFILE_ID_MINPATHFEE,m_LocalRoadNo, m_LocalStaNo, 1),
GetBaseInfo(PFILE_ID_HOLIDAY,m_LocalRoadNo, m_LocalStaNo, 1), GetBaseInfo(PFILE_ID_ISSUER_LIST,m_LocalRoadNo, m_LocalStaNo, 1),GetBaseInfo(PFILE_ID_DISCOUNT,m_LocalRoadNo, m_LocalStaNo, 1),
GetBaseInfo(PFILE_ID_LANE,m_LocalRoadNo, m_LocalStaNo, 1), GetBaseInfo(PFILE_ID_GAPPOINTALL,m_LocalRoadNo, m_LocalStaNo, 1),GetBaseInfo(PFILE_ID_BIGAPPOINT,m_LocalRoadNo, m_LocalStaNo, 1),
GetBaseInfo(PFILE_ID_SNBLACKLIST,m_LocalRoadNo, m_LocalStaNo, 1), GetBaseInfo(PFILE_ID_SNBLACKLISTINC,m_LocalRoadNo, m_LocalStaNo, 1),GetBaseInfo(PFILE_ID_EMERCARALL,m_LocalRoadNo, m_LocalStaNo, 1),
GetBaseInfo(PFILE_ID_EMERCARINC,m_LocalRoadNo, m_LocalStaNo, 1));
#else
return QString("%2-%3-%4-%5-%6-%7-%8-%9-%10-%11-%12-%13")
.arg(GetBaseInfo(PFILE_ID_BASICINFO,m_LocalRoadNo, m_LocalStaNo, 1),GetBaseInfo(PFILE_ID_MINPATHFEE,m_LocalRoadNo, m_LocalStaNo, 1),
GetBaseInfo(PFILE_ID_HOLIDAY,m_LocalRoadNo, m_LocalStaNo, 1), GetBaseInfo(PFILE_ID_ISSUER_LIST,m_LocalRoadNo, m_LocalStaNo, 1),GetBaseInfo(PFILE_ID_DISCOUNT,m_LocalRoadNo, m_LocalStaNo, 1),
GetBaseInfo(PFILE_ID_LANE,m_LocalRoadNo, m_LocalStaNo, 1), GetBaseInfo(PFILE_ID_GAPPOINTALL,m_LocalRoadNo, m_LocalStaNo, 1),GetBaseInfo(PFILE_ID_BIGAPPOINT,m_LocalRoadNo, m_LocalStaNo, 1),
GetBaseInfo(PFILE_ID_SNBLACKLIST,m_LocalRoadNo, m_LocalStaNo, 1), GetBaseInfo(PFILE_ID_SNBLACKLISTINC,m_LocalRoadNo, m_LocalStaNo, 1),GetBaseInfo(PFILE_ID_EMERCARALL,m_LocalRoadNo, m_LocalStaNo, 1),
GetBaseInfo(PFILE_ID_EMERCARINC,m_LocalRoadNo, m_LocalStaNo, 1));
#endif
}
bool CParamMan::IsHoliday()
{
QMutexLocker lock(&m_Mutex);
int index = GetIndex(PFILE_ID_HOLIDAY, 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 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;i<arrProvFeeInfo.count();i++)
{
ProvCount++;
objProvFee = arrProvFeeInfo.at(i).toObject();
if(objProvFee["prov"].toString() == QString::number(m_LocalAreaNo))
{
InProvCashTotal += objProvFee["pFee"].toInt();
InProvInCashTotal += objProvFee[pFeeName].toInt();
InProvMileAge += objProvFee["pM"].toInt();
}else{
OutProvCashTotal += objProvFee["pFee"].toInt();
OutProvInCashTotal += objProvFee[pFeeName].toInt();
}
}
return true;
}
}
}
WRITE_LOG("查询最小费额失败:enID=%sexID=%s,VehType=%d", enID.toUtf8().data(), exID.toUtf8().data(), VehType);
return false;
}
#ifdef PARAMMANAGER_LANE
bool CParamMan::GetMinFee(const QString &enID, const QString &exID,const int roadNo, const int staNo,const int CardType,const int VehType, CFeeCalcInfo &fee)
{
QMutexLocker lock(&m_Mutex);
InitFeeCalcInfo(fee);
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())
{
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;i<arrProvFeeInfo.count();i++)
{
fee.ProvCount++;
objProvFee = arrProvFeeInfo.at(i).toObject();
splitCash = objProvFee["pFee"].toInt();
splitInCash = objProvFee[pFeeName].toInt();
intervalsGroup = objProvFee["group"].toString();
payFeeGroup = objProvFee["pFg"].toString();
intervalsCount = GetGroupCount(payFeeGroup);
if(CardType == CARD_TYPE_STORE || CardType == CARD_TYPE_TOLLY)
{
feeGroup = GetGroupFee95(payFeeGroup, 95);
discountFeeGroup = GetGroupDiscount(payFeeGroup, feeGroup);
}else{
feeGroup = payFeeGroup;
discountFeeGroup = GetGroup("0", intervalsCount);
}
mVerGroup = GetGroup(objProvFee["mVer"].toString(), intervalsCount);
pVerGroup = GetGroup(objProvFee["pVer"].toString(), intervalsCount);
provId = objProvFee["prov"].toString();
if(objProvFee["prov"].toString() == QString::number(m_LocalAreaNo))
{
fee.InProvCashTotal += splitCash;
fee.InProvInCashTotal += splitInCash;
fee.FeeMileAge += objProvFee["pM"].toInt();
}else{
fee.OutProvCashTotal += splitCash;
fee.OutProvInCashTotal += splitInCash;
}
splitFee = QString("{\"splitAmount\":%1,\"feeGroup\":\"%2\",\"tollIntervalsGroup\":\"%3\",\"discountFeeGroup\":\"%4\",\"payFee\":%5,\"rateModeVersionGroup\":\"%6\",\"chargePayGroup\":\"%7\",\"tollIntervalsCount\":%8,\"provinceId\":%9,\"rateParaVersionGroup\":\"%10\"}").
arg(splitInCash).arg(feeGroup).arg(intervalsGroup).arg(discountFeeGroup).arg(splitCash).arg(mVerGroup).arg(payFeeGroup).
arg(intervalsCount).arg(provId).arg(pVerGroup);
if(splitFeeAll.isEmpty())
{
splitFeeAll = splitFee;
}else{
splitFeeAll += QString(",") + splitFee;
}
}
splitFeeAll = QString("{\"provinceFees\":[%1]}").arg(splitFeeAll);
strncpy(fee.splitFeeMinFee, splitFeeAll.toUtf8().data(), sizeof(fee.splitFeeMinFee)-1);
return true;
}
}
}
WRITE_LOG("查询最小费额失败:enID=%sexID=%s,VehType=%d", enID.toUtf8().data(), exID.toUtf8().data(), VehType);
return false;
}
//对比并合并费率结果
//结果存放在Fee中
int CParamMan::MinFeeCompare(const CFeeCalcInfo &minFee, const int CardType, CFeeCalcInfo &Fee, QString &ErrorInfo)
{
int ErrorCode = -1;
if(CheckMinFee(minFee.Cash, Fee.Cash, Fee.ExitFeeType, Fee.FeeVehType, CardType, ErrorCode, ErrorInfo))
{
Fee.MinFee = minFee.MinFee;
Fee.MinFee95 = minFee.MinFee95;
Fee.MinFeeMileAge = minFee.MinFeeMileAge;
strncpy(Fee.MinFeeVer, minFee.MinFeeVer, sizeof(Fee.MinFeeVer)-1);
strncpy(Fee.splitFeeMinFee, minFee.splitFeeMinFee, sizeof(Fee.splitFeeMinFee)-1);
Fee.FeeRate = GetFeeRate(Fee.OutProvCashTotal, Fee.InProvCashTotal, Fee.ProvCount, minFee.MinFee);
Fee.FeeBoadPlay = 1;
}else{
//取最小费额计费
Fee.ExitFeeType = minFee.ExitFeeType; //计费方式
Fee.Cash= minFee.Cash; //应收金额
Fee.InCash= minFee.InCash; //实收金额
Fee.TransFee= minFee.TransFee; //实际扣费金额(卡面扣款金额)
Fee.ProvCount= minFee.ProvCount; //通行省份
Fee.OutProvCashTotal= minFee.OutProvCashTotal; //外省累计应收金额
Fee.OutProvInCashTotal= minFee.OutProvInCashTotal; //外省累计实收金额
Fee.FeeMileAgeTotal= minFee.FeeMileAgeTotal; //本省计费里程
Fee.InProvCashTotal= minFee.InProvCashTotal; //本省累计应收金额
Fee.InProvInCashTotal= minFee.InProvInCashTotal; //本省累计实收金额
Fee.FeeMileAge= minFee.FeeMileAge; //本次计费里程
Fee.MinFee = minFee.MinFee;
Fee.MinFee95 = minFee.MinFee95;
Fee.MinFeeMileAge = minFee.MinFeeMileAge;
strncpy(Fee.MinFeeVer, minFee.MinFeeVer, sizeof(Fee.MinFeeVer)-1);
strncpy(Fee.splitFeeMinFee, minFee.splitFeeMinFee, sizeof(Fee.splitFeeMinFee)-1);
Fee.FeeBoadPlay = ErrorCode - (ERROR_CODE_BASE_CALCFEE + 0x20);
Fee.FeeRate = GetFeeRate(Fee.OutProvCashTotal, Fee.InProvCashTotal, Fee.ProvCount, minFee.MinFee);
}
return ErrorCode;
}
#endif
//读取base目录下的Lane.dbf
bool CParamMan::ReadLaneParam()
{
if(m_LaneOpt.bLoaded == 0)
{
m_LaneOpt.bLoaded = 1;
m_LaneOpt.MinETCRate = 950;
m_LaneOpt.MaxETCRate = 3000;
m_LaneOpt.MinCPCRate = 1000;
m_LaneOpt.MaxCPCRate = 5000;
m_LaneOpt.MaxHCRate = 6000;
m_LaneOpt.MaxOnLineRate = 8000;
m_LaneOpt.MaxHCOnLineRate = 15000;
QMutexLocker lock(&m_Mutex);
int index = GetIndex(PFILE_ID_LANE, 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;
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