1375 lines
48 KiB
C++
Raw Normal View History

2025-03-12 11:08:50 +08:00

/**********************************************************************************
* @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"
2025-03-12 18:14:45 +08:00
#include "pub_utility_api/I18N.h"
2025-03-12 11:08:50 +08:00
#include "db_api_ex/CDbApi.h"
#include "rdb_api/CRdbAccess.h"
//#include "alarm_server_api/AlarmCommonDef.h"
#include "../include/SessionApi.h"
2025-03-12 18:14:45 +08:00
#include "../module_alarm/DataMngThread.hpp"
2025-03-12 11:08:50 +08:00
#include "DTOs.hpp"
#include "SimpleCtrl.hpp"
2025-03-12 14:17:01 +08:00
using namespace iot_dbms;
using namespace iot_service;
2025-03-12 11:08:50 +08:00
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()
{
//< 析构时会自动关闭连接
2025-03-12 14:17:01 +08:00
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
2025-03-12 11:08:50 +08:00
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解析失败" );
}
2025-03-12 14:17:01 +08:00
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_WRITE );
2025-03-12 11:08:50 +08:00
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;
2025-03-12 14:17:01 +08:00
return iot_public::getUTCMsecFromLocalTime( year, month, day, hour, minute, 0, 0 );
2025-03-12 11:08:50 +08:00
}
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;
}
2025-03-12 18:14:45 +08:00
if ( regionId != "" )
2025-03-12 11:08:50 +08:00
{
2025-03-12 18:14:45 +08:00
const char *szMsg = "请求错误:按区域搜索未启用";
2025-03-12 11:08:50 +08:00
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 );
}
}
}
2025-03-12 14:17:01 +08:00
iot_dbms::CDbApi objDbConn( DB_CONN_MODEL_READ );
2025-03-12 11:08:50 +08:00
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" );
2025-03-12 18:14:45 +08:00
if( content != "" )
{
strCondition += QString(" content like '%%1%'").arg(urldecode(*content).c_str());
strCondition += " and ";
}
2025-03-12 11:08:50 +08:00
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, "数据库查询错误" );
}
2025-03-12 18:14:45 +08:00
//LOGDEBUG( "SQL语句如下\n%s", strSql.toUtf8().constData());
2025-03-12 11:08:50 +08:00
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;
2025-03-12 14:54:22 +08:00
if ( spPermApi->GetSpeFunc( "FUNC_SPE_ALARM_VIEW", vecRegionId, vecLocationId ) != iotSuccess )
2025-03-12 11:08:50 +08:00
{
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;
2025-03-12 14:54:22 +08:00
if ( spPermApi->GetSpeFunc( "FUNC_SPE_ALARM_VIEW", vecRegionId, vecLocationId ) != iotSuccess )
2025-03-12 11:08:50 +08:00
{
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 );
}
2025-03-12 18:14:45 +08:00
////////////////////////////////////////////////////////////////////////
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");
//}
2025-03-12 11:08:50 +08:00
} //namespace module_alarm
} //namespace web_server