2025-03-12 18:14:45 +08:00

1375 lines
48 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**********************************************************************************
* @file SimpleCtrl.cpp
* @brief 使用oatpp简单api的控制器类
* @author yikenan
* @versiong 1.0
* @date 2021/12/27
**********************************************************************************/
#include <string>
#include <vector>
#include <map>
#include "boost/algorithm/string.hpp"
#include "pub_logger_api/logger.h"
#include "pub_utility_api/TimeUtil.h"
#include "pub_utility_api/I18N.h"
#include "db_api_ex/CDbApi.h"
#include "rdb_api/CRdbAccess.h"
//#include "alarm_server_api/AlarmCommonDef.h"
#include "../include/SessionApi.h"
#include "../module_alarm/DataMngThread.hpp"
#include "DTOs.hpp"
#include "SimpleCtrl.hpp"
using namespace iot_dbms;
using namespace iot_service;
namespace web_server
{
namespace module_alarm
{
CSimpleCtrl::CSimpleCtrl( std::shared_ptr<oatpp::data::mapping::ObjectMapper> &objMapper )
: oatpp::web::server::api::ApiController( objMapper )
{
}
//< 默认告警颜色
static const std::vector<std::string> g_vecDefaultAlmColor = {"ffff00", "ffBD00", "ff7E00", "ff3F00", "ff0000"};
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleCtrl::findAlarmcolor()
{
//< 析构时会自动关闭连接
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
if ( !objDbConn.open())
{
LOGERROR( "findAlarmcolor(): 打开数据库失败" );
return createResponse( Status::CODE_500, "打开数据库失败" );
}
//LOGINFO( "数据库地址=[%s],名称=[%s]", objDbConn.getCurrentDbPara().getHostName().toUtf8().data(),
// objDbConn.getCurrentDbPara().getDatabaseName().toUtf8().data());
QString strSql;
QSqlQuery objQuery;
//< 查询颜色配置
std::map<int, std::string> mapCfgColor;
{
//< SQL中写明列名代码中无需再判断列是否存在
strSql = "SELECT id,color FROM alarm_color ORDER BY id";
if ( objDbConn.execute( strSql, objQuery ))
{
bool bOk = true;
while ( objQuery.next())
{
const int nId = objQuery.value( 0 ).toInt( &bOk );
if ( !bOk )
{
LOGERROR( "findAlarmcolor(): id字段转int失败跳过" );
continue;
}
mapCfgColor[nId] = objQuery.value( 1 ).toString().toStdString();
}
}
else
{
LOGERROR( "findAlarmcolor(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
}
}
//< SQL中写明列名代码中无需再判断列是否存在
strSql = "SELECT priority_id,priority_name FROM alarm_level_define ORDER BY priority_id";
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "findAlarmcolor(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
return createResponse( Status::CODE_500, "数据库查询错误" );
}
auto spResp = dto::CAlmColor::createShared();
while ( objQuery.next())
{
auto spOne = dto::COneAlmColor::createShared();
const int nId = objQuery.value( 0 ).toInt();
spOne->id = objQuery.value( 0 ).toString().toStdString();
spOne->name = objQuery.value( 1 ).toString().toStdString();
auto it = mapCfgColor.find( nId );
if ( it == mapCfgColor.end())
{
//< 没找到
if ( nId >= ( int ) g_vecDefaultAlmColor.size())
spOne->color = *g_vecDefaultAlmColor.rbegin();
else if ( nId < 0 )
spOne->color = *g_vecDefaultAlmColor.begin();
else
spOne->color = g_vecDefaultAlmColor[nId];
}
else
{
spOne->color = it->second;
}
spResp->push_back( spOne );
}
return createDtoResponse( Status::CODE_200, spResp );
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleCtrl::insertColor( const oatpp::String &strReq )
{
auto spReq = getDefaultObjectMapper()->readFromString<dto::CAlmColor>( strReq );
if ( !spReq )
{
LOGERROR( "insertColor(): 请求解析失败,请求内容:%s", strReq->c_str());
return createResponse( Status::CODE_400, "请求json解析失败" );
}
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_WRITE );
if ( !objDbConn.open())
{
LOGERROR( "insertColor(): 打开数据库失败" );
return createResponse( Status::CODE_500, "打开数据库失败" );
}
//LOGINFO( "数据库地址=[%s],名称=[%s]", objDbConn.getCurrentDbPara().getHostName().toUtf8().data(),
// objDbConn.getCurrentDbPara().getDatabaseName().toUtf8().data());
if ( !objDbConn.transaction())
{
LOGERROR( "insertColor(): 开启事务失败" );
return createResponse( Status::CODE_500, "开启事务失败" );
}
//< 清空alarm_color表
bool bRc = objDbConn.execute( "TRUNCATE TABLE alarm_color" );
//< 插入
if ( bRc )
{
QList<QList<QVariant> > objInsertVal;
for ( const auto &it:*spReq )
{
objInsertVal.push_back( {it->id->c_str(), it->color->c_str()} );
}
bRc = objDbConn.insert( "alarm_color", {"id", "color"}, objInsertVal, 100 );
}
//< 提交
if ( bRc )
{
if ( !objDbConn.commit())
{
LOGERROR( "insertColor(): 提交事务失败" );
return createResponse( Status::CODE_500, "提交事务失败" );
}
}
else
{
LOGERROR( "insertColor(): 数据库操作失败" );
objDbConn.rollback();
return createResponse( Status::CODE_500, "数据库操作失败" );
}
auto spResp = oatpp::DTO::Fields<String>::createShared();
spResp->push_back( {"reflag", "succ"} );
spResp->push_back( {"reflagInfo", "保存成功"} );
return createDtoResponse( Status::CODE_200, spResp );
}
inline unsigned char from_hex( unsigned char ch )
{
if ( ch <= '9' && ch >= '0' )
ch -= '0';
else if ( ch <= 'f' && ch >= 'a' )
ch -= 'a' - 10;
else if ( ch <= 'F' && ch >= 'A' )
ch -= 'A' - 10;
else
ch = 0;
return ch;
}
inline std::string urldecode( const std::string &str )
{
using namespace std;
string result;
string::size_type i;
for ( i = 0; i < str.size(); ++i )
{
if ( str[i] == '+' )
{
result += ' ';
}
else if ( str[i] == '%' && str.size() > i + 2 )
{
const unsigned char ch1 = from_hex( str[i + 1] );
const unsigned char ch2 = from_hex( str[i + 2] );
const unsigned char ch = ( ch1 << 4 ) | ch2;
result += ch;
i += 2;
}
else
{
result += str[i];
}
}
return result;
}
inline int64 getTime( const char *pCharTime )
{
if ( !pCharTime )
return -1;
int year, month, day, hour, minute;
sscanf( pCharTime, "%04d-%02d-%02d %02d:%02d", &year, &month, &day, &hour, &minute );
// std::cout << pCharTime <<"|||| "<<year << " " << month << " "<< day << " "<< hour << " "<< minute << std::endl;
return iot_public::getUTCMsecFromLocalTime( year, month, day, hour, minute, 0, 0 );
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response> CSimpleCtrl::queryEventMsFromMySql(
const oatpp::String &content, const oatpp::String &priority, const oatpp::String &location,
const oatpp::String &devType, const oatpp::String &type, const oatpp::String &regionId,
const oatpp::String &startTime, const oatpp::String &endTime, const oatpp::Int32 &orderType,
const oatpp::String &orderFlag, const oatpp::Int16 &pageSize, const oatpp::Int16 &page )
{
int64 nStartTimeMsec = 0, nEndTimeMsec = 0;
std::string decodedPriority,decodedLocation,decodedDevType,decodedType;
std::vector<std::string> vecPriority, vecLocation, vecDevType, vecType;
QString strOrderType;
{
if ( startTime == "" || endTime == "" )
{
const char *szMsg = "请求错误:时间为空";
LOGERROR( "%s", szMsg );
return createResponse( Status::CODE_400, szMsg );
}
nStartTimeMsec = getTime( urldecode( *startTime ).c_str());
nEndTimeMsec = getTime( urldecode( *endTime ).c_str());
if ( -1 == nStartTimeMsec || -1 == nEndTimeMsec )
{
const char *szMsg = "请求错误:时间错误";
LOGERROR( "%s", szMsg );
return createResponse( Status::CODE_400, szMsg );
}
if ( nStartTimeMsec > nEndTimeMsec )
{//< 不作为错误,调换
const int64 nTemp = nEndTimeMsec;
nEndTimeMsec = nStartTimeMsec;
nStartTimeMsec = nTemp;
}
if ( regionId != "" )
{
const char *szMsg = "请求错误:按区域搜索未启用";
LOGERROR( "%s", szMsg );
return createResponse( Status::CODE_400, szMsg );
}
// 0 时间1优先组2位置3责任区4事件类型
if ( orderType < 0 || orderType > 5 )
{
const char *szMsg = "请求错误:orderType必须为时间";
LOGERROR( "%s", szMsg );
return createResponse( Status::CODE_400, szMsg );
}
else
{
switch (orderType) {
case 0:
strOrderType = "time_stamp";
break;
case 1:
strOrderType = "priority";
break;
case 2:
strOrderType = "location_id";
break;
case 3:
strOrderType = "region_id";
break;
case 4:
strOrderType = "alm_type";
break;
}
}
if ( pageSize <= 0 )
{
const char *szMsg = "请求错误:pagesize必须大于0";
LOGERROR( "%s", szMsg );
return createResponse( Status::CODE_400, szMsg );
}
if ( page <= 0 )
{
const char *szMsg = "请求错误:size必须大于0";
LOGERROR( "%s", szMsg );
return createResponse( Status::CODE_400, szMsg );
}
if ( orderFlag != "asc" && orderFlag != "desc" )
{
const char *szMsg = "请求错误:orderFlag必须为asc或者desc";
LOGERROR( "%s", szMsg );
return createResponse( Status::CODE_400, szMsg );
}
if ( priority != "" )
{
decodedPriority = urldecode(*priority);
boost::split( vecPriority, decodedPriority, boost::is_any_of( ";" ));
if ( vecPriority.empty())
{
const char *szMsg = "请求错误:错误的priority参数";
LOGERROR( "%s", szMsg );
return createResponse( Status::CODE_400, szMsg );
}
}
if ( location != "" )
{
decodedLocation = urldecode(*location);
boost::split( vecLocation, decodedLocation, boost::is_any_of( ";" ));
if ( vecLocation.empty())
{
const char *szMsg = "请求错误:错误的location参数";
LOGERROR( "%s", szMsg );
return createResponse( Status::CODE_400, szMsg );
}
}
if ( devType != "" )
{
decodedDevType = urldecode(*devType);
boost::split( vecDevType, decodedDevType, boost::is_any_of( ";" ));
if ( vecDevType.size() != 1 )
{
const char *szMsg = "请求错误:devType请求参数数量为1或0";
LOGERROR( "%s", szMsg );
return createResponse( Status::CODE_400, szMsg );
}
}
if ( type != "" )
{
decodedType = urldecode(*type);
boost::split( vecType, decodedType, boost::is_any_of( ";" ));
if ( vecType.empty())
{
const char *szMsg = "请求错误:错误的type参数";
LOGERROR( "%s", szMsg );
return createResponse( Status::CODE_400, szMsg );
}
}
}
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
if ( !objDbConn.open())
{
const char *szMsg = "打开数据库失败";
LOGERROR( "%s", szMsg );
return createResponse( Status::CODE_500, szMsg );
}
QString strSql = "select "
" count(*) "
" from his_event ";
// 构造查询条件
QString strCondition = "";
{ // vecPriority,vecLocation,vecDevType,vecType;
auto addCondtion = [&strCondition]( std::vector<std::string> &vecCondition, const std::string &condName )
{
if ( !vecCondition.empty())
{
strCondition += " ( ";
for ( const std::string &x : vecCondition )
{
strCondition += QString( " " ) + condName.c_str() + "=" + x.c_str() + " or";
}
strCondition.chop( 3 );
strCondition += " ) ";
strCondition += " and ";
}
};
addCondtion( vecPriority, "priority" );
addCondtion( vecLocation, "location_id" );
addCondtion( vecDevType, "dev_type" );
addCondtion( vecType, "alm_type" );
if( content != "" )
{
strCondition += QString(" content like '%%1%'").arg(urldecode(*content).c_str());
strCondition += " and ";
}
if ( strCondition != "" )
{
strCondition = " and " + strCondition;
strCondition.chop( 5 ); // delete " and "
}
// 添加排序条件
strCondition += QString(" order by ") + strOrderType + " " + orderFlag->c_str() ;
strCondition = QString( " where " ) + " time_stamp > " + QString::number( nStartTimeMsec )
+ " and time_stamp < " + QString::number( nEndTimeMsec ) + strCondition ;
}
strSql += strCondition;
QSqlQuery objQuery;
//先查询符合条件的数量
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "queryEventMsFromMySql(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
return createResponse( Status::CODE_500, "数据库查询错误" );
}
//LOGDEBUG( "SQL语句如下\n%s", strSql.toUtf8().constData());
auto spResp = dto::EventMsDto::createShared();
spResp->rows = {};
while ( objQuery.next())
{
spResp->records = objQuery.value( 0 ).toString().toInt();
}
spResp->page = page;
spResp->pageSize = pageSize;
spResp->total = ( spResp->records / pageSize ) + 1;
// 填充id到desc的map
std::map<int, String> alarmTypeMap;
std::map<int, String> statuMap;
std::map<int, String> locationMap;
std::map<int, String> levelMap;
std::map<int, String> devTypeMap;
std::map<int, String> regionMap;
{
auto queryIdtoDesc = [&objDbConn, &objQuery, &strSql]( const char *tableName, const char *idCol,
const char *descCol, std::map<int, String> &mapResult )
{
//< SQL中写明列名代码中无需再判断列是否存在
strSql = QString( "SELECT %1,%2 FROM %3 ORDER BY %1" ).arg( idCol ).arg( descCol ).arg( tableName );
objQuery.clear();
if ( objDbConn.execute( strSql, objQuery ))
{
bool bOk = true;
while ( objQuery.next())
{
const int nId = objQuery.value( 0 ).toInt( &bOk );
if ( !bOk )
{
LOGERROR( "queryIdtoDesc(): id字段转int失败跳过, tableName:%s", tableName );
continue;
}
mapResult[nId] = objQuery.value( 1 ).toString().toStdString();
}
}
else
{
LOGERROR( "queryIdtoDesc(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
}
LOGDEBUG( "SQL语句如下\n%s", strSql.toUtf8().constData());
};
queryIdtoDesc( "alarm_type_define", "type_id", "type_name", alarmTypeMap );
queryIdtoDesc( "alarm_status_define", "alarm_type", "display_name", statuMap );
queryIdtoDesc( "sys_model_location_info", "location_id", "DESCRIPTION", locationMap );
queryIdtoDesc( "alarm_level_define", "PRIORITY_ID", "PRIORITY_NAME", levelMap );
queryIdtoDesc( "dev_type_def", "DEV_TYPE_ID", "DESCRIPTION", devTypeMap );
queryIdtoDesc( "region_info", "REGION_ID", "DESCRIPTION", regionMap );
}
// 再查询所有结果
{
strSql = "select "
"alm_type,alm_status,alm_style" // 0 1 2
",time_stamp,location_id,content,priority" // 3 4 5 6
",sub_system,dev_type,region_id,dev_group_tag" // 7 8 9 10
",key_id_tag,confirm_time,confirm_user_id,confirm_node_name" // 11 12 13 14
" from his_event ";
strSql += strCondition;
// page pageSize转换 这里是页数相关
int64 offset = ( int64 ) pageSize * ( int64 ) ( page - 1 );
strSql += QString( " limit " ) + QString::number( pageSize ) + " offset " + QString::number( offset );
objQuery.clear();
if ( !objDbConn.execute( strSql, objQuery ))
{
LOGERROR( "queryEventMsFromMySql(): 查询错误SQL语句如下\n%s", strSql.toUtf8().constData());
return createResponse( Status::CODE_500, "数据库查询错误" );
}
LOGDEBUG( "SQL语句如下\n%s", strSql.toUtf8().constData());
// 填充id到desc的lambda
auto assignDescVal = []( const std::map<int, String> &mapId2Desc, int nId, const char *tableName,
oatpp::String &strVal )
{
auto it = mapId2Desc.find( nId );
if ( it == mapId2Desc.end())
{
( void ) tableName; // 避免 unused parameter 编译器告警
//< 不记录日志,有些告警的设备类型、责任区就是没有的
//< 或者建模删了类型、责任区、区域等,老的事件记录找不到对应的信息
//LOGERROR( "id not found,id:%d,table:%s", nId, tableName );
}
else
{
strVal = it->second;
}
};
while ( objQuery.next())
{
auto spOne = dto::EventRecordRowDto::createShared();
spOne->devType = objQuery.value( 8 ).toString().toStdString();
spOne->confirmTime = objQuery.value( 12 ).toString().toStdString();
spOne->confirmNodeName = objQuery.value( 14 ).toString().toStdString();
spOne->confirm_user_id = objQuery.value( 13 ).toString().toStdString();
spOne->statu = objQuery.value( 2 ).toString().toStdString(); // alm_status
spOne->priority = objQuery.value( 6 ).toString().toStdString();
spOne->type = objQuery.value( 0 ).toString().toStdString(); //alm_type
spOne->content = objQuery.value( 5 ).toString().toStdString();
spOne->regionId = objQuery.value( 9 ).toString().toStdString();
spOne->location = objQuery.value( 4 ).toString().toStdString();
assignDescVal( alarmTypeMap, objQuery.value( 0 ).toInt(), "alarm_type_define", spOne->typeName );
assignDescVal( statuMap, objQuery.value( 2 ).toInt(), "alarm_status_define", spOne->statuName );
assignDescVal( locationMap, objQuery.value( 4 ).toInt(), "sys_model_location_info", spOne->locationName );
assignDescVal( levelMap, objQuery.value( 6 ).toInt(), "alarm_level_define", spOne->priorityName );
assignDescVal( devTypeMap, objQuery.value( 8 ).toInt(), "dev_type_def", spOne->devTypeName );
assignDescVal( regionMap, objQuery.value( 9 ).toInt(), "region_info", spOne->regionName );
spOne->time = QDateTime::fromMSecsSinceEpoch( objQuery.value( 3 ).toLongLong()).toString(
"yyyy-MM-dd HH:mm:ss:zzz" ).toStdString();
spResp->rows->push_back( spOne );
}
}
spResp->operateFlag = true;
return createDtoResponse( Status::CODE_200, spResp );
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
CSimpleCtrl::queryAlarmTreeMs( const std::shared_ptr<IncomingRequest> &spRequest )
{
// 获取用户
auto spPermApi = getSessionApi()->getCurPermApi( spRequest );
if ( !spPermApi )
{
LOGERROR( "未登录无法获取用户ID" );
return createResponse( Status::CODE_400, "未登录" );
}
// 获取责任区id集合、位置id集合
std::set<int> setRegionId;
std::set<int> setLocationId;
{
std::vector<int> vecRegionId;
std::vector<int> vecLocationId;
if ( spPermApi->GetSpeFunc( "FUNC_SPE_ALARM_VIEW", vecRegionId, vecLocationId ) != iotSuccess )
{
LOGERROR( "GetSpeFunc 执行失败" );
return createResponse( Status::CODE_500, "GetSpeFunc 执行失败" );
}
for ( auto nId:vecRegionId )
setRegionId.emplace( nId );
for ( auto nId:vecLocationId )
setLocationId.emplace( nId );
}
// 创建返回的dto
auto spResp = dto::CAlarmTreeMs::createShared();
spResp->rows = oatpp::Vector<oatpp::Object<dto::CAlarmTreeMsRow >>::createShared();
CRdbAccess objRdb;
// 查询位置
if ( objRdb.open( 1, "sys_model_location_info" ))
{
CVarType objDesc;
for ( const auto nId : setLocationId )
{
const int nIndex = objRdb.searchRecordByKey( &nId );
if ( nIndex >= 0 )
{
if ( objRdb.getColumnValueByIndex( nIndex, "description", objDesc ))
{
auto spItem = dto::CAlarmTreeMsRow::createShared();
//spItem->treePCode = "";
spItem->treeCode = std::to_string( nId );
spItem->name = objDesc.c_str();
spResp->rows->emplace_back( std::move( spItem ));
}
else
LOGERROR( "实时库取值失败" );
}
}
objRdb.close();
}
else
LOGERROR( "打开实时库表失败" );
//< 查询设备组
if ( objRdb.open( 1, "dev_group" ))
{
CRdbQueryResult objResult;
std::vector<std::string> vecSelectColumn;
vecSelectColumn.emplace_back( "tag_name" );
vecSelectColumn.emplace_back( "description" );
vecSelectColumn.emplace_back( "location_id" );
vecSelectColumn.emplace_back( "region_id" );
if ( objRdb.select( objResult, vecSelectColumn ))
{
const int nRcdCnt = objResult.getRecordCount();
CVarType objTagName, objDesc, objLocationId, objRegionId;
for ( int i = 0; i < nRcdCnt; i++ )
{
if ( objResult.getColumnValue( i, 0, objTagName )
&& objResult.getColumnValue( i, 1, objDesc )
&& objResult.getColumnValue( i, 2, objLocationId )
&& objResult.getColumnValue( i, 3, objRegionId ))
{
if ( setLocationId.count( objLocationId.toInt()) <= 0 )
continue;
if ( setRegionId.count( objRegionId.toInt()) <= 0 )
continue;
auto spItem = dto::CAlarmTreeMsRow::createShared();
spItem->treePCode = objLocationId.toStdString();
spItem->treeCode = objTagName.c_str();
spItem->name = objDesc.c_str();
spResp->rows->emplace_back( std::move( spItem ));
}
else
LOGERROR( "实时库取值失败" );
}
}
else
LOGERROR( "实时库查询失败" );
objRdb.close();
}
else
LOGERROR( "打开实时库表失败" );
return createDtoResponse( Status::CODE_200, spResp );
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
CSimpleCtrl::queryEventConditionMs( /*const oatpp::Int32 &type, const oatpp::Int32 &id,*/
const std::shared_ptr<IncomingRequest> &spRequest )
{
// todo 参数未用
// 获取用户
auto spPermApi = getSessionApi()->getCurPermApi( spRequest );
if ( !spPermApi )
{
LOGERROR( "未登录无法获取用户ID" );
return createResponse( Status::CODE_400, "未登录" );
}
// 获取责任区id集合、位置id集合
std::vector<int> vecRegionId;
std::vector<int> vecLocationId;
if ( spPermApi->GetSpeFunc( "FUNC_SPE_ALARM_VIEW", vecRegionId, vecLocationId ) != iotSuccess )
{
LOGERROR( "GetSpeFunc 执行失败" );
return createResponse( Status::CODE_500, "GetSpeFunc 执行失败" );
}
// 创建返回的dto
auto spDto = dto::CEventConditionMs::createShared();
spDto->mapData = dto::CEventConditionMsMapData::createShared();
// 查询设备类型
CRdbAccess objRdb;
if ( objRdb.open( 1, "dev_type_def" ))
{
CRdbQueryResult objResult;
std::vector<std::string> vecSelectColumn;
vecSelectColumn.emplace_back( "dev_type_id" );
vecSelectColumn.emplace_back( "tag_name" );
vecSelectColumn.emplace_back( "description" );
if ( objRdb.select( objResult, vecSelectColumn ))
{
const int nRcdCnt = objResult.getRecordCount();
if ( nRcdCnt > 0 )
{
spDto->mapData->devType = oatpp::Vector<oatpp::Object<dto::CEventConditionMsItem >>::createShared();
CVarType v0, v1, v2;
for ( int i = 0; i < nRcdCnt; i++ )
{
if ( objResult.getColumnValue( i, 0, v0 )
&& objResult.getColumnValue( i, 1, v1 )
&& objResult.getColumnValue( i, 2, v2 ))
{
auto spItem = dto::CEventConditionMsItem::createShared();
spItem->id = v0.toStdString();
spItem->code = v1.toStdString();
spItem->name = v2.toStdString();
spDto->mapData->devType->emplace_back( std::move( spItem ));
}
else
LOGERROR( "实时库取值失败" );
}
}
}
else
LOGERROR( "实时库查询失败" );
objRdb.close();
}
else
LOGERROR( "打开实时库表失败" );
// 查询告警类型
if ( objRdb.open( 1, "alarm_type_define" ))
{
CRdbQueryResult objResult;
std::vector<std::string> vecSelectColumn;
vecSelectColumn.emplace_back( "type_id" );
vecSelectColumn.emplace_back( "type_name" );
if ( objRdb.select( objResult, vecSelectColumn ))
{
const int nRcdCnt = objResult.getRecordCount();
if ( nRcdCnt > 0 )
{
spDto->mapData->alarmType = oatpp::Vector<oatpp::Object<dto::CEventConditionMsItem >>::createShared();
CVarType v0, v1;
for ( int i = 0; i < nRcdCnt; i++ )
{
if ( objResult.getColumnValue( i, 0, v0 )
&& objResult.getColumnValue( i, 1, v1 ))
{
auto spItem = dto::CEventConditionMsItem::createShared();
spItem->id = v0.toStdString();
spItem->name = v1.toStdString();
// switch ( v0.toInt())
// {
// case ALM_TYPE_DI_CHANGE:
// spItem->code = "ALM_TYPE_DI_CHANGE";
// break;
// case ALM_TYPE_AI_OVER:
// spItem->code = "ALM_TYPE_AI_OVER";
// break;
// case ALM_TYPE_SOE:
// spItem->code = "ALM_TYPE_SOE";
// break;
// case ALM_TYPE_OPERATE:
// spItem->code = "ALM_TYPE_OPERATE";
// break;
// case ALM_TYPE_SYSTEM:
// spItem->code = "ALM_TYPE_SYSTEM";
// break;
// default:
// break;
// }
spDto->mapData->alarmType->emplace_back( std::move( spItem ));
}
else
LOGERROR( "实时库取值失败" );
}
}
}
else
LOGERROR( "实时库查询失败" );
objRdb.close();
}
else
LOGERROR( "打开实时库表失败" );
// 查询专业
if ( objRdb.open( 1, "sys_model_sub_system_info" ))
{
CRdbQueryResult objResult;
std::vector<std::string> vecSelectColumn;
vecSelectColumn.emplace_back( "sub_system_id" );
vecSelectColumn.emplace_back( "tag_name" );
vecSelectColumn.emplace_back( "description" );
if ( objRdb.select( objResult, vecSelectColumn ))
{
const int nRcdCnt = objResult.getRecordCount();
if ( nRcdCnt > 0 )
{
spDto->mapData->subSystem = oatpp::Vector<oatpp::Object<dto::CEventConditionMsItem >>::createShared();
CVarType v0, v1, v2;
for ( int i = 0; i < objResult.getRecordCount(); i++ )
{
if ( objResult.getColumnValue( i, 0, v0 )
&& objResult.getColumnValue( i, 1, v1 )
&& objResult.getColumnValue( i, 2, v2 ))
{
auto spItem = dto::CEventConditionMsItem::createShared();
spItem->id = v0.toStdString();
spItem->code = v1.toStdString();
spItem->name = v2.toStdString();
spDto->mapData->subSystem->emplace_back( std::move( spItem ));
}
else
LOGERROR( "实时库取值失败" );
}
}
}
else
LOGERROR( "实时库查询失败" );
objRdb.close();
}
else
LOGERROR( "打开实时库表失败" );
// 查询责任区
if ( objRdb.open( 1, "region_info" ))
{
CVarType objTagName;
CVarType objDesc;
for ( const auto nId : vecRegionId )
{
const int nIndex = objRdb.searchRecordByKey( &nId );
if ( nIndex >= 0 )
{
if ( objRdb.getColumnValueByIndex( nIndex, "tag_name", objTagName )
&& objRdb.getColumnValueByIndex( nIndex, "description", objDesc ))
{
auto spItem = dto::CEventConditionMsItem::createShared();
spItem->id = std::to_string( nId );
spItem->code = objTagName.c_str();
spItem->name = objDesc.c_str();
if ( !spDto->mapData->regionInfo )
spDto->mapData->regionInfo = oatpp::Vector<oatpp::Object<dto::CEventConditionMsItem >>::createShared();
spDto->mapData->regionInfo->emplace_back( std::move( spItem ));
}
else
LOGERROR( "实时库取值失败" );
}
}
objRdb.close();
}
else
LOGERROR( "打开实时库表失败" );
// 查询告警等级
if ( objRdb.open( 1, "alarm_level_define" ))
{
CRdbQueryResult objResult;
std::vector<std::string> vecSelectColumn;
vecSelectColumn.emplace_back( "priority_id" );
vecSelectColumn.emplace_back( "sound_file_name" );
vecSelectColumn.emplace_back( "priority_name" );
if ( objRdb.select( objResult, vecSelectColumn ))
{
const int nRcdCnt = objResult.getRecordCount();
if ( nRcdCnt > 0 )
{
spDto->mapData->alarmLevel = oatpp::Vector<oatpp::Object<dto::CEventConditionMsItem >>::createShared();
CVarType v0, v1, v2;
for ( int i = 0; i < nRcdCnt; i++ )
{
if ( objResult.getColumnValue( i, 0, v0 )
&& objResult.getColumnValue( i, 1, v1 )
&& objResult.getColumnValue( i, 2, v2 ))
{
auto spItem = dto::CEventConditionMsItem::createShared();
spItem->id = v0.toStdString();
spItem->code = v1.toStdString();
spItem->name = v2.toStdString();
spDto->mapData->alarmLevel->emplace_back( std::move( spItem ));
}
else
LOGERROR( "实时库取值失败" );
}
}
}
else
LOGERROR( "实时库查询失败" );
objRdb.close();
}
else
LOGERROR( "打开实时库表失败" );
// 查询位置
if ( objRdb.open( 1, "sys_model_location_info" ))
{
CVarType objTagName;
CVarType objDesc;
for ( const auto nId : vecLocationId )
{
const int nIndex = objRdb.searchRecordByKey( &nId );
if ( nIndex >= 0 )
{
if ( objRdb.getColumnValueByIndex( nIndex, "tag_name", objTagName )
&& objRdb.getColumnValueByIndex( nIndex, "description", objDesc ))
{
auto spItem = dto::CEventConditionMsItem::createShared();
spItem->id = std::to_string( nId );
spItem->code = objTagName.c_str();
spItem->name = objDesc.c_str();
if ( !spDto->mapData->location )
spDto->mapData->location = oatpp::Vector<oatpp::Object<dto::CEventConditionMsItem >>::createShared();
spDto->mapData->location->emplace_back( std::move( spItem ));
}
else
LOGERROR( "实时库取值失败" );
}
}
objRdb.close();
}
else
LOGERROR( "打开实时库表失败" );
// 返回数据
spDto->operateFlag = true;
return createDtoResponse( Status::CODE_200, spDto );
}
////////////////////////////////////////////////////////////////////////
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
CSimpleCtrl::getAlarmLevelCount(const std::shared_ptr<IncomingRequest> &request)
{
auto spResp = dto::CAlmLevelResp::createShared();
spResp->data = dto::CAlmLevelData::createShared();
spResp->data->relationship = dto::CAlmLevelRelation::createShared();
spResp->data->data = {};
spResp->data->databaseType = std::string(I18N( "接口" ));
// 列出所有参数,不一定用的到,暂时注释不实现
QString strAreaCode,strDimensions;
//,strAlarmLevel,strOrderBy,strLimit;
int nShowSubSet;
//nTop;
// 检查参数
bool bParaOk = true;
QString strTmp = request->getQueryParameter( "showSubSet" ).getValue( "" ).c_str();
nShowSubSet = strTmp.toInt(&bParaOk);
if ( !bParaOk )
{
const std::string strMsg = I18N( "无效的请求参数" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
strAreaCode = request->getQueryParameter( "areaCode" ).getValue( "" ).c_str();
strDimensions = request->getQueryParameter( "dimensions" ).getValue( "" ).c_str();
QStringList listAreaCode = strAreaCode.split(":",QString::SkipEmptyParts);
// 检查areadCode
if( listAreaCode.size() != 2 || listAreaCode.at(0) != "location")
{
const std::string strMsg = I18N( "无效的请求参数不支持location以外的areaCode" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
// 打开数据库
CDbApi objDb(DB_CONN_MODEL_READ);
if ( !objDb.open() )
{
const std::string strMsg = I18N( "获取模型可读关系库失败" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
// 验证location存在
if( listAreaCode.at(0) == "location")
{
// 查找location是否存在
QSqlQuery objQuery;
QString sSql = QString("select tag_name from sys_model_location_info where location_id='%1'").arg(listAreaCode.at(1));
if ( !objDb.execute(sSql,objQuery) )
{
const std::string strMsg = I18N( "查询关系库表 sys_model_location_info 失败" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
if( !objQuery.next() )
{
const std::string strMsg = I18N( "location不存在" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
}
// 获取所有的设备组
QMap<QString,QString> subset;
if( listAreaCode.at(0) == "location" )
{
QSqlQuery objQuery;
QString sSql = QString("select tag_name,description from dev_group where location_id='%1'").arg(listAreaCode.at(1));
if ( !objDb.execute(sSql,objQuery) )
{
const std::string strMsg = I18N( "查询关系库表 dev_group 失败" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
while( objQuery.next() )
{
subset[objQuery.value(0).toString()] = objQuery.value(1).toString();
}
}
//< 查询告警颜色配置
QMap<int, QString> mapCfgColor;
QMap<int, QString> mapCfgDesc;
{
QSqlQuery objQuery;
//< SQL中写明列名代码中无需再判断列是否存在
QString sSql = "SELECT id,color FROM alarm_color ORDER BY id";
if ( objDb.execute( sSql, objQuery ))
{
bool bOk = true;
while ( objQuery.next())
{
const int nId = objQuery.value( 0 ).toInt( &bOk );
if ( !bOk )
{
continue;
}
mapCfgColor[nId] = objQuery.value( 1 ).toString();
}
}
objQuery.clear();
//< SQL中写明列名代码中无需再判断列是否存在
sSql = "SELECT priority_id,priority_name FROM alarm_level_define ORDER BY priority_id";
if ( !objDb.execute( sSql, objQuery ))
{
const std::string strMsg = I18N( "查询关系库表 alarm_level_define 失败" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
while ( objQuery.next() )
{
const int nId = objQuery.value( 0 ).toInt();
QString desc = objQuery.value( 1 ).toString();
QString color;
auto it = mapCfgColor.find( nId );
if ( it == mapCfgColor.end())
{
//< 没找到
if ( nId >= ( int ) g_vecDefaultAlmColor.size())
color = *g_vecDefaultAlmColor.rbegin()->c_str();
else if ( nId < 0 )
color = *g_vecDefaultAlmColor.begin()->c_str();
else
color = g_vecDefaultAlmColor[nId].c_str();
}
else
{
color = *it;
}
mapCfgDesc[nId] = desc;
mapCfgColor[nId] = color;
}
}
QStringList listDimensions = strDimensions.split(",",QString::SkipEmptyParts);
if( listDimensions.size() != 2 )
{
const std::string strMsg = I18N( "无效的请求参数,dimensions不支持一个参数" );
LOGERROR( "getAlarmLevelCount()%s", strMsg.c_str());
spResp->code = 400;
spResp->message = strMsg;
return createDtoResponse( Status::CODE_200, spResp );
}
QMap<QString,int> mapAlmSize;
for(const auto &almLevelId_keys : mapCfgColor.keys())
{
for(const auto &itSub : subset.keys() )
{
QString key = QString("%1_%2").arg( QString::number( almLevelId_keys ) )
.arg( itSub );
mapAlmSize[key] = 0;
}
}
int nVer = 0;
std::vector<CLiveAlmSp> vecAlm;
CDataMngThread::getInstance()->getAllAlm(nVer,vecAlm);
for ( const auto &it : vecAlm )
{
if(!it->hasDevGroupTag())
{
continue;
}
if(!it->isVisible())
{
continue;
}
QString key = QString("%1_%2").arg( QString::number( it->getPriority() ) )
.arg( it->getDevGroupTag().c_str() );
if(mapAlmSize.find(key) != mapAlmSize.end())
{
mapAlmSize[key] += 1;
}
}
for(const auto &almLevelId_keys : mapCfgColor.keys())
{
for(const auto &itSub : subset.keys() )
{
QString key = QString("%1_%2").arg( QString::number( almLevelId_keys ) )
.arg( itSub );
auto oneUnit = dto::CAlmLevelDataUnit::createShared();
oneUnit->level_color = mapCfgColor[almLevelId_keys].toStdString();
oneUnit->level_name = mapCfgDesc[almLevelId_keys].toStdString();
oneUnit->alarm_level = QString::number(almLevelId_keys).toStdString();
oneUnit->code = itSub.toStdString();
oneUnit->hasChildren = false;
oneUnit->address_id = QString("dev_group:%1").arg(itSub).toStdString();
oneUnit->name = subset[itSub].toStdString();
oneUnit->value = mapAlmSize[key];
spResp->data->data->push_back( oneUnit );
}
}
spResp->code = 200;
const std::string cn_strSuccess = I18N( "成功" );
spResp->message = cn_strSuccess;
return createDtoResponse( Status::CODE_200, spResp );
}
void fillOneAlm(dto::CAlmData::Wrapper& oneAlmResp, const CLiveAlmSp & almSp)
{
oneAlmResp->alm_type = almSp->getAlmType();
oneAlmResp->alm_status = almSp->getAlmStatus();
oneAlmResp->alm_status_desc = almSp->getAlmStatusDesc();
oneAlmResp->alm_logic_status = (int)almSp->getLogicState();
oneAlmResp->timestamp = QString::number(almSp->getTimeStamp()).toStdString();
// spOne->domain_id = almSp->getDomainId();
// spOne->domain_desc = almSp->getDomainDesc();
// spOne->location_id = almSp->getLocationId();
// spOne->app_id = almSp->getAppId();
oneAlmResp->priority = almSp->getPriority();
oneAlmResp->priority_desc = almSp->getPriorityDesc();
oneAlmResp->priority_order = almSp->getPriorityOrder();
// spOne->is_water_alm = almSp->isWaterAlm();
oneAlmResp->uuid_base64 = almSp->getUuidBase64();
oneAlmResp->content = almSp->getContent();
// spOne->sub_system = it->getSubSystem();
// spOne->sub_system_desc = it->getSubSystemDesc();
// spOne->dev_type = it->getDevType();
// spOne->dev_type_desc = it->getDevTypeDesc();
// spOne->has_region_id = it->hasRegionId();
// if(it->hasRegionId())
// {
// spOne->region_id = it->getRegionId();
// spOne->region_desc = it->getRegionDesc();
// }
// else
// {
// spOne->region_id = -1;
// spOne->region_desc = "";
// }
oneAlmResp->has_dev_group_tag = almSp->hasDevGroupTag();
if(almSp->hasDevGroupTag())
{
oneAlmResp->dev_group_tag = almSp->getDevGroupTag();
}
else
{
oneAlmResp->dev_group_tag = "";
}
oneAlmResp->key_id_tag = almSp->getKeyIdTag();
// oneAlmResp->graph_name = almSp->getGraphName();
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
CSimpleCtrl::getAllAlm()
{
auto spResp = dto::CGetAllAlmResp::createShared();
spResp->data = {};
const std::string cn_strSuccess = I18N( "成功" );
spResp->message = cn_strSuccess;
int nVer = 0;
std::vector<CLiveAlmSp> vecAlm;
CDataMngThread::getInstance()->getAllAlm(nVer,vecAlm);
spResp->version_no = nVer;
for ( auto &spAlm : vecAlm )
{
if ( !spAlm->isVisible() )
continue;
auto spOne = dto::CAlmData::createShared();
fillOneAlm(spOne,spAlm);
spResp->data->push_back( spOne );
}
spResp->size = static_cast<v_int32>(spResp->data->size());
spResp->code = 200;
return createDtoResponse(Status::CODE_200, spResp);
}
std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
CSimpleCtrl::getChgLogAfter(const oatpp::Int32 & version_no)
{
auto spResp = dto::CGetChgLogAfterResp::createShared();
const std::string cn_strSuccess = I18N( "成功" );
spResp->message = cn_strSuccess;
spResp->chg_alm_add = {};
spResp->chg_alm_update = {};
spResp->chg_alm_del = {};
std::vector<CAlmChgLogSp> vecSpChgLog;
if ( !CDataMngThread::getInstance()->getChgLogAfter( version_no, vecSpChgLog ))
{
const std::string cn_strFailed = I18N( "失败" );
spResp->message = cn_strFailed;
spResp->code = 201;
spResp->version_no = version_no;
return createDtoResponse(Status::CODE_200, spResp);
}
if(vecSpChgLog.empty())
{
spResp->version_no = version_no;
return createDtoResponse(Status::CODE_200, spResp);
}
spResp->version_no = ( *vecSpChgLog.rbegin())->getVerNo();
for ( auto &spChgLog:vecSpChgLog )
{
switch ( spChgLog->getChgType())
{
case CAlmChgLog::EN_CT_NULL:
break;
case CAlmChgLog::EN_CT_ADD:
{
const auto &vecRefAlm = spChgLog->getRefAlm();
for ( auto &wpAlm:vecRefAlm )
{
CLiveAlmSp spAlm = wpAlm.lock();
if ( !spAlm )
continue;
if ( !spAlm->isVisible())
continue;
auto spOne = dto::CAlmData::createShared();
fillOneAlm(spOne,spAlm);
spResp->chg_alm_add->push_back( spOne );
}
}
break;
case CAlmChgLog::EN_CT_UPDATE:
{
const auto &vecRefAlm = spChgLog->getRefAlm();
for ( auto &wpAlm:vecRefAlm )
{
CLiveAlmSp spAlm = wpAlm.lock();
if ( !spAlm )
continue;
if ( !spAlm->isVisible())
continue;
auto spOne = dto::CAlmData::createShared();
fillOneAlm(spOne,spAlm);
spResp->chg_alm_update->push_back( spOne );
}
}
break;
case CAlmChgLog::EN_CT_DEL:
{
const auto &vecRefAlm = spChgLog->getRefAlm();
for ( auto &wpAlm:vecRefAlm )
{
CLiveAlmSp spAlm = wpAlm.lock();
if ( !spAlm )
continue;
spResp->chg_alm_del->push_back(spAlm->getUuidBase64());
}
}
break;
default:
break;
}
}
spResp->code = 200;
return createDtoResponse(Status::CODE_200, spResp);
}
// 获得设备告警数量 TODO 待实现
//std::shared_ptr<oatpp::web::protocol::http::outgoing::Response>
//CSimpleCtrl::getDeviceAlarmById(const std::shared_ptr<IncomingRequest> &request)
//{
// return createResponse(Status::CODE_200, "ok");
//}
} //namespace module_alarm
} //namespace web_server