Files
energy_storage/src/protocol/HttpEntity.cpp

1604 lines
62 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.
#include "HttpEntity.h"
#include "database/Dao.h"
#include <functional>
#include "common/Utils.h"
#include "common/Snowflake.h"
#include "app/Application.h"
#include "app/AppData.h"
#include "app/Config.h"
#include "app/Station.h"
#include "app/Device.h"
#include "common/XlsxEntity.h"
static void FieldsToJson(Fields& fields, njson& json)
{
for (auto& item : fields.map())
{
json[item.first] = item.second;
}
}
static void JsonToFields(njson& json, std::vector<std::string> vecKeys, Fields& fields)
{
if (vecKeys.empty())
{
for (auto& item: json.items())
{
auto key = item.key();
auto& val = json[key];
}
}
for (auto& key : vecKeys)
{
if (json.contains(key)) {
switch (json[key].type())
{
case njson::value_t::string: { fields.set(key, json[key].get<std::string>()); } break;
case njson::value_t::boolean: { fields.set(key, json[key].get<bool>()); } break;
case njson::value_t::number_integer: { fields.set(key, json[key].get<int>()); } break;
case njson::value_t::number_unsigned: { fields.set(key, json[key].get<int>()); } break;
case njson::value_t::number_float: { fields.set(key, json[key].get<float>()); } break;
case njson::value_t::null: {} break;
case njson::value_t::object: { fields.set(key, json[key].dump()); } break;
case njson::value_t::array: { fields.set(key, json[key].dump()); } break;
case njson::value_t::binary: {} break;
case njson::value_t::discarded: {} break;
default:
break;
}
}
}
}
static njson FieldsToJsonArray(std::vector<Fields>& vecFields)
{
njson jsonnode = njson::array();
for (auto& fields : vecFields)
{
njson jnode;
for (auto& item : fields.map())
{
jnode[item.first] = item.second;
}
jsonnode.push_back(jnode);
}
return jsonnode;
}
static void GetRequestParams(const httplib::Request& req, const std::vector<std::string>& vecKeys, Fields& fields)
{
if (req.method == "GET")
{
for (auto& key : vecKeys)
{
if (req.has_param(key))
{
fields.set(key, req.get_param_value(key));
}
}
}
else if (req.method == "POST")
{
njson json;
JSON::parse(req.body, json);
JsonToFields(json, vecKeys, fields);
}
}
static void CheckRequiredParams(Fields& params, std::vector<std::string> keys, std::string& errmsg)
{
for (auto& key : keys)
{
if (!params.contains(key))
{
errmsg = "参数[" + key + "]错误";;
return;
}
}
}
class HttpHelper
{
public:
static bool CheckRequestParam(const httplib::Request& req, httplib::Response& resp, const std::vector<std::string>& vecKeys, std::string& errmsg)
{
errmsg = "";
for (auto& key : vecKeys)
{
bool hasParam = false;
if (req.method == "GET")
{
hasParam = req.has_param(key);
}
else
{
hasParam = (req.body.find("\"" + key + "\"") != std::string::npos);
}
if (!hasParam)
{
if (!errmsg.empty()) { errmsg += ","; }
errmsg += "缺少参数[" + key + "]";
}
}
if (!errmsg.empty())
{
return false;
}
return true;
}
static void setPagination(PageInfo& pageinfo, std::vector<Fields> result, njson& json)
{
json["count"] = pageinfo.total;
json["page"] = pageinfo.index;
json["page_size"] = pageinfo.size;
json["data"] = FieldsToJsonArray(result);
}
};
static std::map<std::string, HandlerOptions> g_mapHttpHandlerGet =
{
{"/queryBaseinfo", HandlerOptions(&HttpEntity::logqueryBaseinfoin, {})},
{"/login", HandlerOptions(&HttpEntity::login, {DMUser::ACCOUNT, DMUser::PASSWD})},
{"/queryUserList", HandlerOptions(&HttpEntity::queryUserList, {})},
{"/deleteUser", HandlerOptions(&HttpEntity::deleteUser, { DMUser::USER_ID})},
{"/queryPermissionList", HandlerOptions(&HttpEntity::queryPermissionList, {})},
{"/deletePermission", HandlerOptions(&HttpEntity::deletePermission, { DMPermission::PERMISSION_ID})},
{"/queryRoleList", HandlerOptions(&HttpEntity::queryRoleList, {})},
{"/deleteRole", HandlerOptions(&HttpEntity::deleteRole, { DMRole::ROLE_ID})},
{"/queryStationList", HandlerOptions(&HttpEntity::queryStationList, {})},
{"/deleteStation", HandlerOptions(&HttpEntity::deleteStation, { DMStation::STATION_ID})},
{"/queryStationInfo", HandlerOptions(&HttpEntity::queryStationInfo, { DMStation::STATION_ID})},
{"/queryStationData", HandlerOptions(&HttpEntity::queryStationData, { DMStation::STATION_ID})},
{"/queryStationOverview", HandlerOptions(&HttpEntity::queryStationOverview, {DMStation::STATION_ID})},
{"/queryDeviceList", HandlerOptions(&HttpEntity::queryDeviceList, {})},
{"/deleteDevice", HandlerOptions(&HttpEntity::deleteDevice, { DMDevice::DEVICE_ID})},
{"/queryDevicTypeDef", HandlerOptions(&HttpEntity::queryDevicTypeDef, {})},
{"/queryDevicByCategory", HandlerOptions(&HttpEntity::queryDevicByCategory, {DMStation::STATION_ID, "category"})},
{"/queryDevicCharts", HandlerOptions(&HttpEntity::queryDevicCharts, {DMStation::STATION_ID, "device_id"})},
{"/queryDeviceBCUDetail", HandlerOptions(&HttpEntity::queryDeviceBCUDetail, {DMStation::STATION_ID, "device_id"})},
{"/queryPolicyList", HandlerOptions(&HttpEntity::queryPolicyList, {})},
{"/deletePolicy", HandlerOptions(&HttpEntity::deletePolicy, { DMPolicy::POLICY_ID})},
{"/queryPolicyByType", HandlerOptions(&HttpEntity::queryPolicyByType, {"type"})},
{"/querySystemLogList", HandlerOptions(&HttpEntity::querySystemLogList, {})},
{"/queryAlertLogList", HandlerOptions(&HttpEntity::queryAlertLogList, {})},
{"/queryPredictionDetail", HandlerOptions(&HttpEntity::queryPredictionDetail, {})},
{"/queryStatSystem", HandlerOptions(&HttpEntity::queryStatSystem, {})},
{"/queryStatStation", HandlerOptions(&HttpEntity::queryStatStationGroup, {})},
{"/queryStatTotal", HandlerOptions(&HttpEntity::queryStatTotal, {})},
{"/queryStatDayList", HandlerOptions(&HttpEntity::queryStatDayList, {})},
{"/queryStatDetailList", HandlerOptions(&HttpEntity::queryStatDetailList, {})},
{"/queryStatCharts", HandlerOptions(&HttpEntity::queryStatCharts, {})},
{"/exportStatReport", HandlerOptions(&HttpEntity::exportStatReport, {})},
{"/queryEnvironment", HandlerOptions(&HttpEntity::queryEnvironment, { "station_id"})},
{"/queryServiceApiList", HandlerOptions(&HttpEntity::queryServiceApiList, {})},
{"/deleteServiceApi", HandlerOptions(&HttpEntity::deleteServiceApi, {"api_id"})},
//{"/insert", HandlerOptions(&HttpEntity::insert, {})},
//{"/update", HandlerOptions(&HttpEntity::update, {})},
//{"/delete", HandlerOptions(&HttpEntity::delete, {})},
};
static std::map<std::string, HandlerOptions> g_mapHttpHandlerPost
{
{"/insertUser", HandlerOptions(&HttpEntity::insertUser, { DMUser::ACCOUNT})},
{"/updateUser", HandlerOptions(&HttpEntity::updateUser, { DMUser::USER_ID})},
{"/insertPermission", HandlerOptions(&HttpEntity::insertPermission, { DMPermission::NAME})},
{"/updatePermission", HandlerOptions(&HttpEntity::updatePermission, { DMPermission::PERMISSION_ID})},
{"/insertRole", HandlerOptions(&HttpEntity::insertRole, { DMRole::NAME})},
{"/updateRole", HandlerOptions(&HttpEntity::updateRole, { DMRole::ROLE_ID})},
{"/insertStation", HandlerOptions(&HttpEntity::insertStation, { DMStation::NAME})},
{"/updateStation", HandlerOptions(&HttpEntity::updateStation, { DMStation::STATION_ID})},
{"/insertDevice", HandlerOptions(&HttpEntity::insertDevice, { DMDevice::NAME})},
{"/updateDevice", HandlerOptions(&HttpEntity::updateDevice, { DMDevice::DEVICE_ID})},
{"/insertPolicy", HandlerOptions(&HttpEntity::insertPolicy, { DMPolicy::NAME})},
{"/updatePolicy", HandlerOptions(&HttpEntity::updatePolicy, { DMPolicy::POLICY_ID})},
{"/insertServiceApi", HandlerOptions(&HttpEntity::insertServiceApi, {})},
{"/updateServiceApi", HandlerOptions(&HttpEntity::updateServiceApi, {"api_id"})},
};
bool CheckHttpToken(const httplib::Request& req)
{
// 验证token
std::string token = req.get_param_value("token");
if (!token.empty())
{
User user = Application::data().getUser(token);
if (!user.userId.empty())
{
return true;
}
}
return false;
}
HttpEntity::HttpEntity()
{
for (auto& item : g_mapHttpHandlerGet)
{
std::string name = item.first;
HandlerOptions& handler = item.second;
this->httpsvr.Get(name, [=, &handler](const httplib::Request& req, httplib::Response& resp)
{
this->runHandler(name, handler, req, resp);
});
}
for (auto& item : g_mapHttpHandlerPost)
{
std::string name = item.first;
HandlerOptions& handler = item.second;
this->httpsvr.Post(name, [=](const httplib::Request& req, httplib::Response& resp)
{
this->runHandler(name, handler, req, resp);
});
}
}
void HttpEntity::listen(std::string addr, int port)
{
if (addr.empty()) addr = "0.0.0.0";
spdlog::info("[http] start listen: addr={}:{},token={}", addr, port, Config::option.http.useToken);
httpsvr.listen(addr, port); // 阻塞
}
void HttpEntity::runHandler(std::string name, const HandlerOptions& handler, const httplib::Request& req, httplib::Response& resp)
{
spdlog::info("[http] request: {}", name);
bool useToken = Config::option.http.useToken;
Errcode errcode = Errcode::OK;
std::string errmsg;
if (name != "/login" && useToken)
{
bool ret = CheckHttpToken(req);
errcode = ret ? Errcode::OK : Errcode::ERR_TOKEN;
}
njson jsonresp;
if (errcode == Errcode::OK)
{
if (!HttpHelper::CheckRequestParam(req, resp, handler.requiredKeys, errmsg))
{
errcode = Errcode::ERR_PARAM;
}
else
{
errcode = (this->*(handler.func))(req, jsonresp, errmsg);
}
}
jsonresp["errcode"] = errcode;
jsonresp["errmsg"] = ErrcodeStr(errcode) + (errmsg.empty() ? "" : (":"+errmsg));
resp.set_content(jsonresp.dump(), "text/plain; charset=utf-8");
resp.status = 200;
spdlog::info("[http] request: {}, response: {}.", name, int(errcode));
}
void HttpEntity::registGet(std::string name, void (HttpEntity::* func)(const httplib::Request& req, httplib::Response& resp))
{
this->httpsvr.Get(name, std::bind(func, this, std::placeholders::_1, std::placeholders::_2));
}
Errcode HttpEntity::logqueryBaseinfoin(const httplib::Request& req, njson& json, std::string& errmsg)
{
json["data"] = {
{"encryption", Config::option.http.encryption},
{"encryptKey", Config::option.http.encryptKey},
{"latitude", Config::option.view.latitude},
{"longitude", Config::option.view.longitude},
{"altitude", Config::option.view.altitude}
};
return Errcode::OK;
}
Errcode HttpEntity::login(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string userId;
std::string token;
std::string account = req.get_param_value("account");
std::string passwd = req.get_param_value("passwd");
Fields fields;
auto dao = DaoEntity::create("");
Errcode err = DAO::login(dao, account, passwd, fields);
userId = fields.value(DMUser::USER_ID);
token = Application::data().userLogin(userId, account);
if (err == Errcode::OK)
{
json["token"] = token;
json["account"] = account;
std::vector<Fields> vecPermission;
int roleId = fields.get<int>(DMRole::ROLE_ID);
DAO::queryRolePermission(dao, roleId, vecPermission);
njson nodePermission = njson::array();
std::map<std::string, int> mapParentPos;
for (int i=0; i<vecPermission.size(); ++i)
{
auto& item = vecPermission[i];
if (item.value("parent_id") == "")
{
mapParentPos[item.value("permission_id")] = i;
njson node;
FieldsToJson(item, node);
node["children"] = njson::array();
nodePermission.push_back(node);
}
}
// 重新遍历处理二级子权限,防止父权限信息还未创建时导致错误
for (int i = 0; i<vecPermission.size(); ++i)
{
auto& item = vecPermission[i];
std::string id = item.value("permission_id");
std::string parentId = item.value("parent_id");
if (parentId != "")
{
auto iter = mapParentPos.find(parentId);
if (iter != mapParentPos.end())
{
njson node;
FieldsToJson(item, node);
nodePermission[iter->second]["children"].push_back(node);
}
}
}
json["permission"] = nodePermission;
}
DAO::insertSystemLogUser(token, "用户[" + account + "]登录:" + ErrcodeStr(err), (err==Errcode::OK) ? 1: 0);
return err;
}
Errcode HttpEntity::queryUserList(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string token = req.get_param_value("token");
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryUserList(pageinfo, result);
if (err == Errcode::OK)
{
HttpHelper::setPagination(pageinfo, result, json);
}
//DAO::insertSystemLogUser(token, "查询用户列表:" + ErrcodeStr(err), (err==Errcode::OK) ? 1 : 0);
return err;
}
Errcode HttpEntity::insertUser(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"account", "name", "gender", "age", "phone", "email", "role_id"}, params);
return DAO::insertUser(params);
}
Errcode HttpEntity::updateUser(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"user_id", "account", "name", "gender", "age", "phone", "email", "role_id"}, params);
return DAO::updateUserById(params);
}
Errcode HttpEntity::deleteUser(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string userId = req.get_param_value("user_id");
return DAO::deleteUserById(userId);
}
Errcode HttpEntity::queryPermissionList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryPermissionList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
// 查询所有的角色权限关联
if (err == Errcode::OK)
{
std::map<std::string, int> mapP;
for (int i = 0; i<result.size(); ++i)
{
auto& item = result[i];
std::string id = item.value("permission_id");
mapP[id] = json["data"].size() - 1;
}
std::vector<Fields> vecSubPermission;
DaoEntity::execOnce("SELECT * FROM permission WHERE permission.parent_id IS NOT NULL AND permission.parent_id!='';", vecSubPermission);
for (int i = 0; i<vecSubPermission.size(); ++i)
{
auto& item = vecSubPermission[i];
std::string parentId = item.value("parent_id");
std::string id = item.value("permission_id");
if (!parentId.empty())
{
if (mapP.count(parentId) > 0)
{
int index = mapP[parentId];
njson jsonnode;
FieldsToJson(item, jsonnode);
json["data"][index]["children"].push_back(jsonnode);
}
}
}
}
return err;
}
Errcode HttpEntity::insertPermission(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"name", "describe", "is_open"}, params);
return DAO::insertPermission(params);
}
Errcode HttpEntity::updatePermission(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"permission_id", "name", "describe", "is_open"}, params);
return DAO::updatePermissionById(params);
}
Errcode HttpEntity::deletePermission(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string permissionId = req.get_param_value("permission_id");
return DAO::deletePermissionById(permissionId);
}
Errcode HttpEntity::queryRoleList(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string token = req.get_param_value("page");
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryRoleList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
// 查询所有的角色权限关联
if (err == Errcode::OK)
{
std::vector<Fields> vecPermission;
err = DAO::queryRolePermission(NULL, vecPermission);
if (err != Errcode::OK)
{
return err;
}
std::map<std::string, std::vector<Fields>> mapP;
for (int i = 0; i<vecPermission.size(); ++i)
{
auto& item = vecPermission[i];
std::string roleId = item.value("role_id");
std::string id = item.value("permission_id");
std::string parentId = item.value("parent_id");
mapP[roleId].push_back(vecPermission[i]);
}
for (auto& item : json["data"])
{
auto jsonpermission = njson::array();
std::string roleId = item["role_id"];
std::vector<Fields>& vecP = mapP[roleId];
std::map<std::string, int> mapParentPos;
for (int i = 0; i<vecP.size(); ++i)
{
auto& item = vecPermission[i];
if (item.value("parent_id") == "")
{
mapParentPos[item.value("permission_id")] = i;
njson node;
FieldsToJson(item, node);
node["children"] = njson::array();
jsonpermission.push_back(node);
}
}
// 重新遍历处理二级子权限,防止父权限信息还未创建时导致错误
for (int i = 0; i<vecP.size(); ++i)
{
auto& item = vecP[i];
std::string id = item.value("permission_id");
std::string parentId = item.value("parent_id");
if (parentId != "")
{
auto iter = mapParentPos.find(parentId);
if (iter != mapParentPos.end())
{
njson node;
FieldsToJson(item, node);
jsonpermission[iter->second]["children"].push_back(node);
}
}
}
item["permission"] = jsonpermission;
}
}
return err;
}
Errcode HttpEntity::queryRolePermission(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"role_id"}, params);
if (!params.contains("role_id")) { errmsg = "缺少参数[role_id]"; return Errcode::ERR_PARAM; }
return Errcode::OK;
}
Errcode HttpEntity::insertRole(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"name", "describe", "is_open", "permission"}, params);
return DAO::insertRole(params);
};
Errcode HttpEntity::updateRole(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"role_id", "name", "describe", "is_open", "permission"}, params);
auto roleId = params.value("role_id");
std::string permission = params.remove("permission");
auto dao = DaoEntity::create("");
auto err = Errcode::OK;
if (params.size() > 1)
{
err = DAO::updateRoleById(dao, params);
}
if (err == Errcode::OK && !permission.empty())
{
njson jsonarray;
if (JSON::parse(permission, jsonarray))
{
std::vector<Fields> vecFields;
for (auto& item: jsonarray)
{
Fields fields;
fields.set("role_id", roleId);
fields.set("permission_id", item["permission_id"].get<std::string>());
fields.set("is_open", item["is_open"].get<std::string>());
fields.set("is_view", item["is_view"].get<std::string>());
fields.set("is_add", item["is_add"].get<std::string>());
fields.set("is_edit", item["is_edit"].get<std::string>());
fields.set("is_del", item["is_del"].get<std::string>());
vecFields.push_back(fields);
}
err = DAO::updateRolePermission(dao, roleId, vecFields);
}
}
return err;
};
Errcode HttpEntity::deleteRole(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string roleId = req.get_param_value(DMRole::ROLE_ID);
return DAO::remove(NULL, DMRole::TABLENAME, DMRole::ROLE_ID, roleId);
};
Errcode HttpEntity::queryStationList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryStationList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
};
Errcode HttpEntity::insertStation(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"name", "address", "lon", "lat", "tel", "capacity", "status"}, params);
return DAO::insertStation(params);
};
Errcode HttpEntity::updateStation(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "name", "address", "lon", "lat", "tel", "capacity", "status", "work_mode", "policy_id", "operation_date"}, params);
std::string stationId = params.value("station_id");
params.check("capacity", "", "0.0");
params.check("lon", "", "0.0");
params.check("lat", "", "0.0");
params.check("status", "", "1");
params.check("policy_id", "", "NULL");
params.check("operation_date", "", "NULL");
Errcode err = DAO::updateStationById(params);
if (err == Errcode::OK)
{
std::string sql = "SELECT s.*, p.name policy_name, p.`type` policy_type, p.value FROM station s LEFT JOIN policy p ON s.policy_id=p.policy_id"
" WHERE s.station_id='" + stationId + "';";
std::vector<Fields> result;
int ret = DaoEntity::execOnce(sql, result);
if (ret != 0)
{
spdlog::error("[http] update station success, set station cache error, station_id={}", stationId);
}
else
{
auto station = Application::data().getStation(Utils::toInt(stationId));
if (result.size() > 0 && station)
{
station->setFields(result[0]);
}
}
}
if (params.contains("station_id") && params.contains("work_mode"))
{
int stationId = params.get<int>("station_id");
int workmode = params.get<int>("work_mode");
auto station = Application::data().getStation(stationId);
if (station)
{
station->setGarewayWorkMode();
}
}
return err;
};
Errcode HttpEntity::deleteStation(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string primaryKey = DMStation::STATION_ID;
return DAO::remove(NULL, DMStation::TABLENAME, primaryKey, req.get_param_value(primaryKey));
};
Errcode HttpEntity::queryStationOverview(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id"}, params);
std::string stationId = params.value("station_id");
if (stationId.empty())
{
return Errcode::ERR_PARAM;
}
auto dao = DaoEntity::create("");
std::vector<Fields> result;
// 运行模式
std::string sql = "SELECT * FROM station WHERE station_id='" + stationId + "';";
int ret = dao->exec(sql, result);
if (ret != 0)
{
return Errcode(ret);
}
if (result.size() > 0)
{
json["data"]["work_mode"] = result[0].get<int>("work_mode");
}
// 储能设备:总功率,数量
// 充电设备:总功率,数量
// 光伏设备:总功率,数量
sql = R"(SELECT d.`type`, count(1) count, ddt.name typename, ddt.category FROM device d
LEFT JOIN def_device_type ddt ON ddt.device_type_id=d.`type` WHERE d.station_id=')" + stationId + "' GROUP BY `type`;";
ret = dao->exec(sql, result);
if (ret != 0)
{
return Errcode(ret);
}
njson jsonStorage = njson::parse(R"({"category":1, "gateway":0, "count":0, "power":0.0})");
auto station = Application::data().getStation(Utils::toInt(stationId));
jsonStorage["workmode"] = station ? station->getGatewayMode() : "--";
njson jsonCharge = njson::parse(R"({"category":2, "count":0, "power":0.0})");
njson jsonSolar = njson::parse(R"({"category":3, "count":0, "power":0.0})");
njson jsonSecurity = njson::parse(R"({"category":4, "count":0, "power":0.0})");
auto videoInfo = Config::getVideoInfo(stationId);
if (videoInfo)
{
jsonSecurity["host"] = videoInfo->host;
jsonSecurity["port"] = videoInfo->port;
jsonSecurity["user"] = videoInfo->user;
jsonSecurity["passwd"] = videoInfo->passwd;
}
for (auto& fields : result)
{
int category = fields.get<int>("category");
int count = fields.get<int>("count");
switch (category)
{
case 1: { jsonStorage["count"] = jsonStorage["count"].get<int>() + count; } break;
case 2: { jsonCharge["count"] = jsonCharge["count"].get<int>() + count; } break;
case 3: { jsonSolar["count"] = jsonSolar["count"].get<int>() + count; } break;
case 4: { jsonSecurity["count"] = jsonSecurity["count"].get<int>() + count; } break;
default:
break;
}
}
// 从运行数据中读取功率信息(待补充)
json["data"]["device_group"] = {jsonStorage, jsonCharge, jsonSolar, jsonSecurity};
return Errcode::OK;
}
Errcode HttpEntity::queryStationInfo(const httplib::Request& req, njson& json, std::string& errmsg)
{
// 查询场站的基础配置信息
std::string stationId = req.get_param_value("station_id");
if (stationId.empty())
{
return Errcode::ERR_PARAM;
}
std::string sql = "SELECT * FROM " + DMStation::TABLENAME + " WHERE station_id=" + stationId + ";";
std::vector<Fields> result;
Errcode err = DAO::exec(NULL, sql, result);
if (err != Errcode::OK)
{
return err;
}
if (result.size() == 0)
{
return Errcode::ERR_DATA_NUL;
}
auto& fields = result[0];
njson jsondata;
std::string attr = fields.remove(DMStation::ATTR);
JSON::parse(attr, jsondata);
FieldsToJson(fields, jsondata);
json["data"] = jsondata;
return Errcode::OK;
// work_mode: 运行模式:
// capacity: 储能容量:
// {"batttey_type": "磷酸铁锂", "cooling_type":"风冷", "voltage_rated":"300", "power_rated": "1500"}
// batttey_type: 电池类型:
// cooling_type: 冷却方式:
// voltage_rated: 电池额定电压:
// power_rated: PCS额定功率
}
Errcode HttpEntity::queryStationData(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string stationId = req.get_param_value("station_id");
auto station = Application::data().getStation(Utils::toInt(stationId));
njson jsondata;
if (station)
{
// 温度, 电压、电流、功率、功率因数、
jsondata["voltage"] = Utils::toStr(station->voltage, 0);
jsondata["current"] = Utils::toStr(station->current, 0);
jsondata["power"] = Utils::toStr(station->power, 0);
jsondata["powerFactor"] = Utils::toStr(station->powerFactor, 0);
jsondata["envTemp"] = Utils::toStr(station->temperature, 0);
jsondata["envhum"] = Utils::toStr(station->humidity, 0);
jsondata["aircStatus"] = station->aircStatus;
jsondata["coolingStatus"] = station->coolingStatus;
}
json["data"] = jsondata;
return Errcode::OK;
}
Errcode HttpEntity::queryDeviceList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryDeviceList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
};
Errcode HttpEntity::insertDevice(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; }
Errcode err = DAO::insertDevice(params);
if (err == Errcode::OK)
{
int stationId = params.get<int>("station_id");
auto station = Application::data().getStation(stationId);
if (station) { station->addDevice(params); }
}
return err;
};
Errcode HttpEntity::updateDevice(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"device_id", "station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
Errcode err = DAO::updateDeviceById(params);
if (err == Errcode::OK)
{
int stationId = params.get<int>("station_id");
auto station = Application::data().getStation(stationId);
if (station) { station->addDevice(params); }
}
return err;
};
Errcode HttpEntity::deleteDevice(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string primaryKey = DMDevice::DEVICE_ID;
return DAO::remove(NULL, DMDevice::TABLENAME, primaryKey, req.get_param_value(primaryKey));
};
Errcode HttpEntity::queryDevicTypeDef(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string sql = "SELECT device_type_id, name FROM def_device_type;";
std::vector<Fields> result;
auto err = DAO::exec(NULL, sql, result);
json["data"] = FieldsToJsonArray(result);
return err;
}
Errcode HttpEntity::queryDevicByCategory(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "category"}, params);
if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; }
if (!params.contains("category")) { errmsg = "缺少参数[category]"; return Errcode::ERR_PARAM; }
int stationId = params.get<int>("station_id");
int category = params.get<int>("category");
njson jsondata = njson::array();
auto station = Application::data().getStation(stationId);
if (station)
{
std::vector<std::shared_ptr<Device>> vecDevice;
station->getDeviceByCategory(category, vecDevice);
for(auto& device: vecDevice)
{
if (device->isOpen)
{
njson jsonnode;
jsonnode["stationId"] = stationId;
jsonnode["category"] = category;
jsonnode["device_id"] = device->deviceId;
jsonnode["name"] = device->name;
jsonnode["code"] = device->code;
jsonnode["type"] = device->type;
jsonnode["typename"] = Application::data().getDeviceNameById(device->type);
jsonnode["view"] = 1;
jsonnode["is_online"] = device->online;// ? "在线" : "离线";
jsonnode["is_error"] = device->err;// ? "故障" : "正常";
jsonnode["is_running"] = device->running;// ? "工作" : "空闲";
{
VecPairSS vec;
device->getRuntimeParams(vec);
njson jsonarrayParams = njson::array();
for (auto& item: vec)
{
jsonarrayParams.push_back({{"k", item.first}, {"v", item.second}});
}
jsonnode["params"] = jsonarrayParams;
}
if (device->type == 106)
{
VecPairSS vec;
device->getRuntimeParams1(vec);
njson jsonarrayParams = njson::array();
for (auto& item: vec)
{
jsonarrayParams.push_back({{"k", item.first}, {"v", item.second}});
}
jsonnode["params1"] = jsonarrayParams;
}
jsondata.push_back(jsonnode);
}
}
}
json["data"] = jsondata;
return Errcode::OK;
}
Errcode HttpEntity::queryDevicCharts(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "device_id"}, params);
if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; }
if (!params.contains("device_id")) { errmsg = "缺少参数[device_id]"; return Errcode::ERR_PARAM; }
int stationId = params.get<int>("station_id");
int deviceId = params.get<int>("device_id");
auto device = Application::data().getDevice(stationId, deviceId);
std::vector<std::string> vecV, vecI, vecP;
if (device)
{
device->getCacheVoltage(vecV);
device->getCacheCurrent(vecI);
device->getCachePower(vecP);
}
json["data"] = {{"V", vecV}, {"I", vecI}, {"P", vecP}};
return Errcode::OK;
}
Errcode HttpEntity::queryDeviceBCUDetail(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "device_id"}, params);
if (!params.contains("station_id")) { errmsg = "缺少参数[station_id]"; return Errcode::ERR_PARAM; }
if (!params.contains("device_id")) { errmsg = "缺少参数[device_id]"; return Errcode::ERR_PARAM; }
int stationId = params.get<int>("station_id");
int deviceId = params.get<int>("device_id");
auto device = Application::data().getDevice(stationId, deviceId);
njson jsondata = njson::array();
if (device)
{
for (int i = 0; i<=device->bcuCount && i<device->vecBCUUnit.size(); ++i)
{
auto& row = device->vecBCUUnit[i];
std::string soc = Utils::toStr(row[0], 1);
std::string soh = Utils::toStr(row[1], 1);
std::string u = Utils::toStr(row[2], 0);
std::string t = Utils::toStr(row[3], 2);
std::string r_i = Utils::toStr(row[4], 0);
jsondata.push_back({{"SOC", soc}, {"SOH", soh}, {"V", u}, {"T", t}, {"R_i", r_i}});
}
}
json["data"] = jsondata;
return Errcode::OK;
}
Errcode HttpEntity::queryPolicyList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryPolicyList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
};
Errcode HttpEntity::insertPolicy(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"type", "name", "describe", "value", "is_open"}, params);
return DAO::insertPolicy(params);
};
Errcode HttpEntity::updatePolicy(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"policy_id", "type", "describe", "value", "is_open"}, params);
return DAO::updatePolicyById(params);
};
Errcode HttpEntity::deletePolicy(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"policy_id"}, params);
return DAO::deletePolicyById(params.value("policy_id"));
};
Errcode HttpEntity::queryPolicyByType(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string type = req.get_param_value("type");
std::string sql = "SELECT policy_id, `type`, name from policy WHERE `type`='" + type + "';";
std::vector<Fields> result;
int ret = DaoEntity::execOnce(sql, result);
return Errcode(ret);
}
Errcode HttpEntity::querySystemLogList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::querySystemLogList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
}
//Errcode insertSystemLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode HttpEntity::updateSystemLog(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"log_id", "status"}, params);
return DAO::updateSystemLogById(params);
}
Errcode HttpEntity::queryAlertLogList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryAlertLogList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
}
//Errcode insertAlertLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode HttpEntity::updateAlertLog(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"log_id", "status"}, params);
return DAO::updateAlertLogById(params);
}
Errcode HttpEntity::queryPredictionDetail(const httplib::Request& req, njson& json, std::string& errmsg)
{
const int num = 144;
std::vector<int> vecStoreIn(num, 0), vecStoreOut(num, 0), vecCharge(num, 0), vecSolar(num, 0), vecSolarP(num, 0);
for (int i = 0; i<num; ++i)
{
vecStoreIn[i] = 0;
vecStoreOut[i] = 0;
vecCharge[i] = 0;
vecSolar[i] = 0;
vecSolarP[i] = 0;
}
json["data"] = {
{"W_store_in", vecStoreIn},
{"W_store_out", vecStoreOut},
{"W_charge", vecCharge},
{"W_solar", vecSolar},
{"P_solar", vecSolarP }
};
return Errcode::OK;
}
Errcode HttpEntity::queryStatSystem(const httplib::Request& req, njson& json, std::string& errmsg)
{
auto& appdata = Application::data();
double incomeTotal {};
double station_num = appdata.getStationCount();
double solarDeviceNum {};
double capacityTotal {};
double electGenTotal {};
double electGridTotal {};
double electStorageIn {};
double electStorageOut {};
for (auto& item : appdata.mapStation)
{
auto& station = item.second;
solarDeviceNum += station->getDeviceCount(3);
capacityTotal += station->capacity;
electGenTotal += station->electGenTotal;
electGridTotal += station->electGridTotal;
electStorageIn += station->electStorageIn;
electStorageOut += station->electStorageOut;
}
njson jsondata;
jsondata["launch_date"] = appdata.launchDate; //: 系统上线启用日期格式yyyy-mm-dd
jsondata["income_total"] = incomeTotal; // : 累计收益精度0.01
jsondata["station_num"] = station_num; // : 能源站数量
jsondata["storage_device_num"] = station_num; //: 储能设备数量
jsondata["solar_device_num"] = solarDeviceNum; //: 光伏设备数量
jsondata["capacity_total"] = capacityTotal; // : 储能总容量kWh精度0.001
jsondata["solar_elect_gen"] = electGenTotal; // : 发电总电量kWh精度0.001
jsondata["solar_elect_grid"] = electGridTotal; // : 入网种电量kWh精度0.001
jsondata["storage_elect_in"] = electStorageIn; // : 储能充电总电量kWh精度0.001
jsondata["storage_elect_out"] = electStorageOut; // : 储能放电总电量kWh精度0.001
json["data"] = jsondata;
return Errcode::OK;
}
Errcode HttpEntity::queryStatStationGroup(const httplib::Request& req, njson& json, std::string& errmsg)
{
njson jsondata = njson::array();
auto dao = DaoEntity::create("");
std::string sql = R"(SELECT s.station_id, s.name station_name, ss.income_elect, ss.income_charge, ss.storage_usage FROM station s LEFT JOIN
(SELECT station_id, SUM(income_elect ) income_elect , SUM(income_charge) income_charge, avg(storage_usage) storage_usage FROM stat_day GROUP BY station_id) AS ss
ON ss.station_id = s.station_id)";
std::vector<Fields> vecStations;
auto err = dao->exec(sql, vecStations);
for (auto& fields: vecStations)
{
njson jsonnode;
jsonnode["station_name"] = fields.value("station_name");
jsonnode["income"] = fields.get<float>("income_elect") + fields.get<float>("income_charge");
jsonnode["usage_rate"] = fields.get<float>("storage_usage");
jsondata.push_back(jsonnode);
}
json["data"] = jsondata;
return Errcode(err);
}
static void VerifyRequstParamsStatDate(Fields& params)
{
if (!params.contains("end_date"))
{
if (!params.contains("start_date"))
{
params.set("end_date", Utils::dateStr());
params.set("start_date", Utils::dateStr(Utils::date() - 86400*7));
}
else
{
params.set("end_date", Utils::dateStr(Utils::time(params.value("start_date") +" 00:00:00") + 86400*7));
}
}
}
static std::string VerifyStatSqlCondition(Fields& params)
{
std::string stationId = params.value("station_id");
std::string category = params.value("category");
std::string dtStart = params.value("start_date");
std::string dtEnd = params.value("end_date");
std::string sqlCondition;
if (!dtStart.empty() && dtEnd.empty())
{
sqlCondition += "dt BETWEEN '" + dtStart + "' AND '" + dtEnd + "'";
}
if (!stationId.empty())
{
if (!sqlCondition.empty()) sqlCondition += " AND ";
sqlCondition += "ss.station_id='" + stationId + "'";
}
if (!category.empty() && category != "0")
{
//if (!sqlCondition.empty()) sqlCondition += " AND ";
//sqlCondition += "ss.category='" + category + "'";;
}
if (!sqlCondition.empty()) { sqlCondition = " WHERE " + sqlCondition; }
return sqlCondition;
}
static std::string GetRequestStatParams(const httplib::Request& req, Fields& params)
{
GetRequestParams(req, {"station_id", "category", "start_date", "end_date"}, params);
VerifyRequstParamsStatDate(params);
return VerifyStatSqlCondition(params);
}
Errcode HttpEntity::queryStatTotal(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
std::string sqlCondition = GetRequestStatParams(req, params);
std::string sql = R"(SELECT
SUM(storage_elect_in) storage_elect_in,
SUM(storage_elect_out) storage_elect_out,
SUM(storage_num_in) storage_num_in,
SUM(storage_num_out) storage_num_out,
SUM(storage_num_err) storage_num_err,
SUM(solar_elect_gen) solar_elect_gen,
SUM(solar_elect_grid) solar_elect_grid,
SUM(solar_num_err) solar_num_err,
AVG(storage_usage) storage_usage,
SUM(charge_elect) charge_elect,
SUM(charge_num) charge_num,
SUM(charge_num_err) charge_num_err,
AVG(charge_usage) charge_usage,
SUM(income_elect) income_elect,
SUM(income_charge) income_charge
FROM stat_day ss)" + sqlCondition + ";";
std::string stationId = params.value("station_id");
njson jsondata;
auto station = Application::data().getStation(Utils::toInt(stationId));
if (station)
{
jsondata["launch_date"] = station->launchDate;
}
std::vector<Fields> result;
DaoEntity::execOnce(sql, result);
if (result.size() > 0)
{
auto& fields = result[0];
// jsondata["launch_date"] = "2025-09-01"; //场站上线日期
// jsondata["station_id"] = station_id;
jsondata["storage_elect_in"] = fields.value("storage_elect_in"); //储能充电电量kWh精度0.001
jsondata["storage_elect_out"] = fields.value("storage_elect_out"); //储能放电电量kWh精度0.001
jsondata["storage_num_in"] = fields.value("storage_elect_out"); //储能设备充电次数
jsondata["storage_num_out"] = fields.value("storage_num_out"); //储能设备放电次数
jsondata["storage_num_err"] = fields.value("storage_num_err"); //储能设备故障次数
jsondata["solar_elect_gen"] = fields.value("solar_elect_gen"); //光伏发电电量kWh精度0.001
jsondata["solar_elect_grid"] = fields.value("solar_elect_grid"); //光伏入网电量kWh精度0.001
jsondata["solar_num_err"] = fields.value("solar_num_err"); //光伏设备故障次数
jsondata["charge_elect"] = fields.value("charge_elect"); //充电设备充电电量kWh精度0.001
jsondata["charge_num"] = fields.value("charge_num"); //充电设备充电次数
jsondata["charge_num_err"] = fields.value("charge_num_err"); //充电设备故障次数
jsondata["income_elect"] = fields.value("income_elect"); //发电收益精度0.01
jsondata["income_charge"] = fields.value("income_charge"); //充电收益精度0.01
jsondata["usage_rate"] = Utils::toStr(float(fields.get<int>("storage_usage")+fields.get<int>("storage_usage"))*0.5f, 0);
json["data"] = jsondata;
}
return Errcode::OK;
}
Errcode HttpEntity::queryStatDayList(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "category", "start_date", "end_date"}, params);
std::string stationId = params.value("station_id");
std::string category = params.value("category");
std::string startDate = params.value("start_date");
std::string endDate = params.value("end_date");
if (endDate.empty())
{
int64_t t = Utils::time();
endDate = Utils::dateStr(t);
startDate = Utils::dateStr(t - 86400*7);
}
std::vector<Fields> result;
auto err = DAO::queryStatStationGroup(NULL, stationId, category, startDate, endDate, result);
if (!startDate.empty() && !endDate.empty())
{
std::map<std::string, Fields*> mapTemp;
for (auto& item: result)
{
auto& dt = item.value("dt");
mapTemp[dt] = &item;
}
int64_t t0 = Utils::time(startDate + " 00:00:00");
int64_t t1 = Utils::time(endDate + " 00:00:00");
int i = 0;
njson jsondata = njson::array();
for (int64_t t = t0; t<=t1; t += 86400)
{
njson jsonrow;
std::string dt = Utils::dateStr(t);
Fields* fields = NULL;
auto iter = mapTemp.find(dt);
if (iter != mapTemp.end()) { fields = iter->second; }
jsonrow["dt"] = dt.substr(5);
jsonrow["storage_elect_in"] = fields ? fields->value("storage_elect_in") : "0";
jsonrow["storage_elect_out"] = fields ? fields->value("storage_elect_out") : "0";
jsonrow["storage_num_in"] = fields ? fields->value("storage_num_in") : "0";
jsonrow["storage_num_out"] = fields ? fields->value("storage_num_out") : "0";
jsonrow["storage_num_err"] = fields ? fields->value("storage_num_err") : "0";
jsonrow["solar_elect_gen"] = fields ? fields->value("solar_elect_gen") : "0";
jsonrow["solar_elect_grid"] = fields ? fields->value("solar_elect_grid") : "0";
jsonrow["solar_num_err"] = fields ? fields->value("solar_num_err") : "0";
jsonrow["storage_usage"] = fields ? fields->value("storage_usage") : "0";
jsonrow["charge_elect"] = fields ? fields->value("charge_elect") : "0";
jsonrow["charge_num"] = fields ? fields->value("charge_num") : "0";
jsonrow["charge_num_err"] = fields ? fields->value("charge_num_err") : "0";
jsonrow["charge_usage"] = fields ? fields->value("charge_usage") : "0";
jsonrow["income_elect"] = fields ? fields->value("income_elect") : "0";
jsonrow["income_charge"] = fields ? fields->value("income_charge") : "0";
jsondata.push_back(jsonrow);
}
json["data"] = jsondata;
}
else
{
json["data"] = FieldsToJsonArray(result);
}
return err;
}
//Errcode HttpEntity::queryStatDayList(const httplib::Request& req, njson& json, std::string& errmsg)
//{
// std::string sqlCondition = GetRequestStatParams(req);
// std::string sql = R"(SELECT ss.*, d.name device_name, ddt.name device_type FROM stat_day ss
// LEFT JOIN device d ON d.device_id = ss.device_id
// LEFT JOIN def_device_type ddt ON ddt.device_type_id = d.`type`)" + sqlCondition + ";";
//
// std::vector<Fields> result;
// int ret = DaoEntity::execOnce(sql, result);
// json["data"] = FieldsToJsonArray(result);
// return Errcode(ret);
//}
Errcode HttpEntity::queryStatDetailList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
Fields params;
GetRequestParams(req, {"station_id", "category", "start_date", "end_date"}, params);
std::vector<Fields> result;
auto err = DAO::queryStatStationList(pageinfo, params, result);
//json["data"] = FieldsToJsonArray(result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
}
Errcode HttpEntity::queryStatCharts(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string dt = req.get_param_value("dt");
std::string stationId = req.get_param_value("station_id");
std::string category = req.get_param_value("category");
if (stationId.empty()) { errmsg = "参数[station_id]错误"; return Errcode::ERR_PARAM; }
if (category.empty()) { errmsg = "参数[category]错误"; return Errcode::ERR_PARAM; }
if (dt.empty()) { dt=Utils::dateStr(); }
njson jsondata;
std::string sql = R"(SELECT hd.*, d.`type` device_type, ddt.category FROM history_day hd
LEFT JOIN device d ON d.device_id = hd.device_id
LEFT JOIN def_device_type ddt ON d.`type` = ddt.device_type_id
WHERE dt=')" + dt + "' AND d.station_id='" + stationId + "' AND ddt.category='" + category + "';";
std::vector<Fields> result;
int ret = DaoEntity::execOnce(sql, result);
if (ret != 0)
{
return Errcode(ret);
}
std::vector<double> vecV;
std::vector<double> vecI;
std::vector<double> vecP;
for (auto fields : result)
{
int datetype = fields.get<int>("datatype"); // 1: 电压2电流3功率
std::string val = fields.value("value"); // JSON 数组(double)
njson jsonval;
if (JSON::parse(val, jsonval))
{
for (int i = 0; i<jsonval.size(); ++i)
{
double val = jsonval[i];
if (datetype == 1)
{
// 电压取最大
i >= vecV.size() ? vecV.push_back(val) : (val > vecV[i] ? (vecV[i] = val, (void)0) : (void)0);
}
else if (datetype == 2)
{
// 电流取最大
i >= vecI.size() ? vecI.push_back(val) : (val > vecI[i] ? (vecI[i] = val, (void)0) : (void)0);
}
else if (datetype == 3)
{
// 功率累加
i >= vecP.size() ? vecP.push_back(val) : (vecP[i] = vecP[i] + val, (void)0);
}
}
}
}
json["data"] = {{"V", vecV}, {"I", vecI}, {"P", vecP}};
return Errcode::OK;
}
Errcode HttpEntity::exportStatReport(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"station_id", "category", "start_date", "end_date"}, params);
CheckRequiredParams(params, {"station_id", "category", "start_date", "end_date"}, errmsg);
if (!errmsg.empty())
{
return Errcode::ERR_PARAM;
}
std::string stationId = params.value("station_id");
std::string category = params.value("category");
std::string startDate = params.value("start_date");
std::string endDate = params.value("end_date");
std::string sql = "SELECT s.name station_name, sd.* FROM stat_day sd LEFT JOIN station s ON sd.station_id=s.station_id";
sql += " WHERE sd.station_id = '" + stationId + "' AND category = '" + category + "'";
sql += " AND dt BETWEEN '" + startDate + "' AND '" + endDate + "2025-09-19' AND sd.category = '1'";
std::string filename;
std::vector<Fields> result;
Errcode err = DAO::exec(NULL, sql, result);
if (result.size() > 0)
{
filename = "export_" + Utils::timeStr(0, "%Y%m%d%H%M%S") + ".xlsx";
XlsxEntity xlsx(Config::option.exportpath + "/" + filename);
std::vector<std::pair<std::string, std::string>> headers;
if (category == "1")
{
headers = {
{"日期", "dt"}, {"场站", "station_name"}, {"类别", "category"},
{"充电电量", "storage_elect_in"}, {"放电电量", "storage_elect_out"},
{"充电次数", "storage_num_in"}, {"放电次数", "storage_num_out"},
{"充电时长", "storage_t_in"}, {"放电时长", "storage_t_out"}
};
}
else if (category == "2")
{
headers = {
{"日期", "dt"}, {"场站", "station_name"}, {"类别", "category"},
{"充电电量", "charge_elect"}, {"充电次数", "charge_num"}, {"充电时长", "charge_t"}
};
}
else if (category == "3")
{
headers = {
{"日期", "dt"}, {"场站", "station_name"}, {"类别", "category"},
{"发电电量", "solar_elect_gen"}, {"入网电量", "solar_elect_grid"}, {"发电时长", "solar_t"},
};
}
for (int row = 0; row<result.size(); ++row)
{
auto& fields = result[row];
if (category == "1") { fields.value("category") = "储能设备"; }
else if (category == "2") { fields.value("category") = "充电设备"; }
else if (category == "3") { fields.value("category") = "发电设备"; }
for (int col = 0; col<headers.size(); ++col)
{
if (row == 0)
{
xlsx.setCell(row+1, col+1, headers[col].first);
}
xlsx.setCell(row+2, col+1, fields.value(headers[col].second));
}
}
xlsx.close();
}
json["data"] = filename;
return err;
}
Errcode HttpEntity::queryEnvironment(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string stationId = req.get_param_value("station_id");
auto& appdata = Application::data();
auto station = appdata.getStation(Utils::toInt(stationId));
if (!station)
{
spdlog::error("[http] request queryEnvironment failed, get station info error, station_id={}", stationId);
return Errcode::ERR_PARAM;
}
njson jsondata;
{ // 温湿度
auto& mapTempHumUnit = station->mapTempHumUnit;
njson nodearray = njson::array();
for (auto iter = mapTempHumUnit.begin(); iter!=mapTempHumUnit.end(); iter++)
{
auto& unit = iter->second;
njson node;
node["pos"] = "#" + std::to_string(iter->first);
node["temp"] = Utils::toStr(unit.temp);
node["hum"] = Utils::toStr(unit.hum);
nodearray.push_back(node);
}
jsondata["temp_hum"] = nodearray;
}
{ //空调
auto& mapAircUnit = station->mapAircUnit;
njson nodearray = njson::array();
for (auto& item: mapAircUnit)
{
auto& unit = item.second;
nodearray.push_back({{"pos", "开关"}, {"status", unit.powerOn == 0 ? "关机" : "开机"}});
nodearray.push_back({{"pos", "启动制冷指令"}, {"status", unit.cooling == 0 ? "启动" : "关闭"}});
nodearray.push_back({{"pos", "启动送风指令"}, {"status", unit.airSupply == 0 ? "关闭" : "启动"}});
nodearray.push_back({{"pos", "启动待机指令"}, {"status", unit.standby == 0 ? "关闭" : "启动"}});
nodearray.push_back({{"pos", "启动加热指令"}, {"status", unit.heating == 0 ? "关闭" : "启动"}});
nodearray.push_back({{"pos", "传感器故障"}, {"status", unit.sensorAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "高低电压告警"}, {"status", unit.voltageAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "高低温告警"}, {"status", unit.tempAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "高低压告警"}, {"status", unit.pressureAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "压缩机告警"}, {"status", unit.compressorAlarm == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "当前温度"}, {"status", std::to_string(unit.temp) + ""}});
nodearray.push_back({{"pos", "当前湿度"}, {"status", std::to_string(unit.hum) + "%"}});
break;
}
jsondata["airc"] = nodearray;
}
{ // 消防
static std::map<int, std::string> mapFireStatusDef = { {0, "正常"}, {1,"预警"}, {2,"火警"} };
std::map<int, string> mapStatusDef = {{0, "无效"}, {1, "掉线"}, {2, "正常"}, {3, "启动"}};
auto& mapFire40Unit = station->mapFire40Unit;
njson nodearray = njson::array();
for (auto iter = mapFire40Unit.begin(); iter!=mapFire40Unit.end(); ++iter)
{
auto& unit = iter->second;
nodearray.push_back({{"pos", "主控状态"}, {"status", unit.statusMain == 0 ? "正常" : (unit.statusMain == 1 ? "预警" : "火警")}});
nodearray.push_back({{"pos", "警铃是否使用"}, {"status", unit.usedAlarm == 0 ? "" : ""}});
nodearray.push_back({{"pos", "警铃状态"}, {"status", mapStatusDef[unit.statusAlarm]}}); // 0无效 1掉线 2正常 3启动
nodearray.push_back({{"pos", "瓶头阀是否使用"}, {"status", unit.usedValve == 0 ? "" : ""}});
nodearray.push_back({{"pos", "瓶头阀状态"}, {"status", mapStatusDef[unit.statusAlarm]}}); // 0无效 1掉线 2正常 3启动
nodearray.push_back({{"pos", "手报是否使用"}, {"status", unit.usedMCP == 0 ? "" : ""}});
nodearray.push_back({{"pos", "手报状态"}, {"status", mapStatusDef[unit.statusAlarm]}}); // 0无效 1掉线 2正常 3启动
break;
}
jsondata["fire40"] = nodearray;
}
{ // 冷机
auto& mapCoolingUnit = station->mapCoolingUnit;
njson nodearray = njson::array();
for (auto& item: mapCoolingUnit)
{
auto& unit = item.second;
njson node;
nodearray.push_back({{"pos", "开关"}, {"status", unit.powerOn == 0 ? "关机" : "开机"}});
nodearray.push_back({{"pos", "采样模式"}, {"status", unit.mode == 0 ? "出水温度" : "电芯温度"}});
nodearray.push_back({{"pos", "制冷状态"}, {"status", unit.cooling == 0 ? "关闭" : "启动"}});
nodearray.push_back({{"pos", "制热状态"}, {"status", unit.heating == 0 ? "关闭" : "启动"}});
nodearray.push_back({{"pos", "高温告警"}, {"status", unit.highTemp == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "低温告警"}, {"status", unit.lowTemp == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "高压告警"}, {"status", unit.highPressure == 0 ? "正常" : "告警"}});
nodearray.push_back({{"pos", "低压告警"}, {"status", unit.lowPressure == 0 ? "正常" : "告警"}});
}
jsondata["cooling"] = nodearray;
}
json["data"] = jsondata;
return Errcode::OK;
}
Errcode HttpEntity::queryServiceApiList(const httplib::Request& req, njson& json, std::string& errmsg)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
std::string sql = "SELECT * FROM serviceapi;" ;
auto err = DAO::exec(NULL, sql, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
}
Errcode HttpEntity::insertServiceApi(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"name", "describe", "params", "is_open"}, params);
if (params.size() == 0) { return Errcode::ERR_PARAM; }
return DAO::insert(NULL, "serviceapi", params);
}
Errcode HttpEntity::updateServiceApi(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"api_id", "name", "describe", "params", "is_open"}, params);
if (params.size() == 0) { return Errcode::ERR_PARAM; }
return DAO::update(NULL, "serviceapi", params, "api_id");
}
Errcode HttpEntity::deleteServiceApi(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"api_id"}, params);
return DAO::remove(NULL, "serviceapi", "api_id", params.value("api_id"));
}