Files
energy_storage/src/protocol/HttpEntity.cpp

2068 lines
80 KiB
C++
Raw Normal View History

2025-08-31 14:38:53 +08:00
#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"
2025-09-04 19:31:04 +08:00
#include "app/Station.h"
#include "app/Device.h"
2025-09-20 16:41:08 +08:00
#include "common/XlsxEntity.h"
2025-08-31 14:38:53 +08:00
static void FieldsToJson(Fields& fields, njson& json)
2025-09-04 19:31:04 +08:00
{
for (auto& item : fields.map())
{
json[item.first] = item.second;
}
}
static void JsonToFields(njson& json, std::vector<std::string> vecKeys, Fields& fields)
2025-09-05 19:44:26 +08:00
{
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;
2025-09-12 18:44:34 +08:00
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;
2025-09-05 19:44:26 +08:00
default:
break;
}
}
}
}
2025-09-04 19:31:04 +08:00
static njson FieldsToJsonArray(std::vector<Fields>& vecFields)
2025-08-31 14:38:53 +08:00
{
njson jsonnode = njson::array();
2025-08-31 14:38:53 +08:00
for (auto& fields : vecFields)
{
njson jnode;
2025-08-31 14:38:53 +08:00
for (auto& item : fields.map())
{
jnode[item.first] = item.second;
}
jsonnode.push_back(jnode);
}
return jsonnode;
}
2025-09-20 16:41:08 +08:00
static void GetRequestParams(const httplib::Request& req, const std::vector<std::string>& vecKeys, Fields& fields)
2025-08-31 14:38:53 +08:00
{
2025-09-04 19:31:04 +08:00
if (req.method == "GET")
2025-08-31 14:38:53 +08:00
{
2025-09-04 19:31:04 +08:00
for (auto& key : vecKeys)
2025-08-31 14:38:53 +08:00
{
2025-09-04 19:31:04 +08:00
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);
2025-08-31 14:38:53 +08:00
}
}
2025-09-20 16:41:08 +08:00
static void CheckRequiredParams(Fields& params, std::vector<std::string> keys, std::string& errmsg)
{
for (auto& key : keys)
{
if (!params.contains(key))
{
errmsg = "参数[" + key + "]错误";;
return;
}
}
}
2025-08-31 14:38:53 +08:00
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)
{
2025-09-05 19:44:26 +08:00
bool hasParam = false;
if (req.method == "GET")
{
hasParam = req.has_param(key);
}
else
{
hasParam = (req.body.find("\"" + key + "\"") != std::string::npos);
}
if (!hasParam)
2025-08-31 14:38:53 +08:00
{
if (!errmsg.empty()) { errmsg += ","; }
errmsg += "缺少参数[" + key + "]";
}
}
if (!errmsg.empty())
{
return false;
}
return true;
}
static void setPagination(PageInfo& pageinfo, std::vector<Fields> result, njson& json)
2025-08-31 14:38:53 +08:00
{
json["count"] = pageinfo.total;
json["page"] = pageinfo.index;
json["page_size"] = pageinfo.size;
json["data"] = FieldsToJsonArray(result);
}
};
2025-09-04 19:31:04 +08:00
static std::map<std::string, HandlerOptions> g_mapHttpHandlerGet =
2025-08-31 14:38:53 +08:00
{
2025-09-19 18:54:36 +08:00
{"/queryBaseinfo", HandlerOptions(&HttpEntity::logqueryBaseinfoin, {})},
2025-08-31 14:38:53 +08:00
{"/login", HandlerOptions(&HttpEntity::login, {DMUser::ACCOUNT, DMUser::PASSWD})},
2025-09-04 19:31:04 +08:00
{"/queryUserList", HandlerOptions(&HttpEntity::queryUserList, {})},
{"/deleteUser", HandlerOptions(&HttpEntity::deleteUser, { DMUser::USER_ID})},
2025-08-31 14:38:53 +08:00
2025-09-04 19:31:04 +08:00
{"/queryPermissionList", HandlerOptions(&HttpEntity::queryPermissionList, {})},
{"/deletePermission", HandlerOptions(&HttpEntity::deletePermission, { DMPermission::PERMISSION_ID})},
2025-08-31 14:38:53 +08:00
2025-09-04 19:31:04 +08:00
{"/queryRoleList", HandlerOptions(&HttpEntity::queryRoleList, {})},
{"/deleteRole", HandlerOptions(&HttpEntity::deleteRole, { DMRole::ROLE_ID})},
2025-08-31 14:38:53 +08:00
2025-09-04 19:31:04 +08:00
{"/queryStationList", HandlerOptions(&HttpEntity::queryStationList, {})},
{"/deleteStation", HandlerOptions(&HttpEntity::deleteStation, { DMStation::STATION_ID})},
{"/queryStationInfo", HandlerOptions(&HttpEntity::queryStationInfo, { DMStation::STATION_ID})},
2025-09-05 19:44:26 +08:00
{"/queryStationData", HandlerOptions(&HttpEntity::queryStationData, { DMStation::STATION_ID})},
{"/queryStationOverview", HandlerOptions(&HttpEntity::queryStationOverview, {DMStation::STATION_ID})},
{"/queryStationTodayU", HandlerOptions(&HttpEntity::queryStationTodayU, {DMStation::STATION_ID, "category"})},
{"/queryStationTodayI", HandlerOptions(&HttpEntity::queryStationTodayI, {DMStation::STATION_ID, "category"})},
{"/queryStationTodayP", HandlerOptions(&HttpEntity::queryStationTodayP, {DMStation::STATION_ID, "category"})},
2025-09-04 19:31:04 +08:00
{"/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"})},
2025-08-31 14:38:53 +08:00
2025-09-04 19:31:04 +08:00
{"/queryPolicyList", HandlerOptions(&HttpEntity::queryPolicyList, {})},
{"/deletePolicy", HandlerOptions(&HttpEntity::deletePolicy, { DMPolicy::POLICY_ID})},
2025-09-19 18:54:36 +08:00
{"/queryPolicyByType", HandlerOptions(&HttpEntity::queryPolicyByType, {"type"})},
2025-09-04 19:31:04 +08:00
{"/querySystemLogList", HandlerOptions(&HttpEntity::querySystemLogList, {})},
2025-08-31 14:38:53 +08:00
2025-09-04 19:31:04 +08:00
{"/queryAlertLogList", HandlerOptions(&HttpEntity::queryAlertLogList, {})},
2025-08-31 14:38:53 +08:00
2025-09-04 19:31:04 +08:00
{"/queryPredictionDetail", HandlerOptions(&HttpEntity::queryPredictionDetail, {})},
2025-08-31 14:38:53 +08:00
2025-09-04 19:31:04 +08:00
{"/queryStatSystem", HandlerOptions(&HttpEntity::queryStatSystem, {})},
2025-09-16 19:38:46 +08:00
{"/queryStatStation", HandlerOptions(&HttpEntity::queryStatStationGroup, {})},
2025-09-04 19:31:04 +08:00
{"/queryStatTotal", HandlerOptions(&HttpEntity::queryStatTotal, {})},
{"/queryStatDayList", HandlerOptions(&HttpEntity::queryStatDayList, {})},
2025-09-16 19:38:46 +08:00
{"/queryStatDetailList", HandlerOptions(&HttpEntity::queryStatDetailList, {})},
{"/queryStatCharts", HandlerOptions(&HttpEntity::queryStatCharts, {})},
2025-09-20 16:41:08 +08:00
{"/exportStatReport", HandlerOptions(&HttpEntity::exportStatReport, {})},
2025-09-20 16:41:08 +08:00
{"/queryEnvironment", HandlerOptions(&HttpEntity::queryEnvironment, { "station_id"})},
{"/queryServiceApiList", HandlerOptions(&HttpEntity::queryServiceApiList, {})},
{"/deleteServiceApi", HandlerOptions(&HttpEntity::deleteServiceApi, {"api_id"})},
2026-03-03 15:51:49 +08:00
{"/queryEGridPeriod", HandlerOptions(&HttpEntity::queryEGridPeriod, {})},
2025-08-31 14:38:53 +08:00
//{"/insert", HandlerOptions(&HttpEntity::insert, {})},
//{"/update", HandlerOptions(&HttpEntity::update, {})},
//{"/delete", HandlerOptions(&HttpEntity::delete, {})},
};
2025-09-04 19:31:04 +08:00
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"})},
{"/updateGatewayParams", HandlerOptions(&HttpEntity::updateGatewayParams, {DMStation::STATION_ID})},
2025-09-04 19:31:04 +08:00
};
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()
2025-08-31 14:38:53 +08:00
{
2025-09-04 19:31:04 +08:00
for (auto& item : g_mapHttpHandlerGet)
2025-08-31 14:38:53 +08:00
{
std::string name = item.first;
HandlerOptions& handler = item.second;
this->httpsvr.Get(name, [=, &handler](const httplib::Request& req, httplib::Response& resp)
2025-08-31 14:38:53 +08:00
{
2025-09-05 19:44:26 +08:00
this->runHandler(name, handler, req, resp);
2025-09-04 19:31:04 +08:00
});
}
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)
{
2025-09-05 19:44:26 +08:00
this->runHandler(name, handler, req, resp);
});
2025-08-31 14:38:53 +08:00
}
}
2025-08-31 14:38:53 +08:00
void HttpEntity::listen(std::string addr, int port)
{
2025-08-31 14:38:53 +08:00
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); // 阻塞
2025-08-31 14:38:53 +08:00
}
2025-09-05 19:44:26 +08:00
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;
2025-09-05 19:44:26 +08:00
if (errcode == Errcode::OK)
{
if (!HttpHelper::CheckRequestParam(req, resp, handler.requiredKeys, errmsg))
{
errcode = Errcode::ERR_PARAM;
}
else
{
errcode = (this->*(handler.func))(req, jsonresp, errmsg);
2025-09-05 19:44:26 +08:00
}
}
jsonresp["errcode"] = errcode;
jsonresp["errmsg"] = ErrcodeStr(errcode) + (errmsg.empty() ? "" : (":"+errmsg));
resp.set_content(jsonresp.dump(), "text/plain; charset=utf-8");
resp.status = 200;
2025-09-19 18:54:36 +08:00
spdlog::info("[http] request: {}, response: {}.", name, int(errcode));
2025-09-05 19:44:26 +08:00
}
2025-08-31 14:38:53 +08:00
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));
}
2025-09-19 18:54:36 +08:00
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)
2025-08-31 14:38:53 +08:00
{
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;
2025-08-31 14:38:53 +08:00
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)
2025-09-05 19:44:26 +08:00
{
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);
}
}
2025-09-05 19:44:26 +08:00
}
json["permission"] = nodePermission;
2025-08-31 14:38:53 +08:00
}
2025-09-24 19:06:31 +08:00
DAO::insertSystemLogUser(token, "用户[" + account + "]登录:" + ErrcodeStr(err), (err==Errcode::OK) ? 1: 0);
2025-08-31 14:38:53 +08:00
return err;
}
Errcode HttpEntity::queryUserList(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
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);
2025-08-31 14:38:53 +08:00
return err;
}
Errcode HttpEntity::insertUser(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"account", "name", "gender", "age", "phone", "email", "role_id"}, params);
2025-08-31 14:38:53 +08:00
return DAO::insertUser(params);
}
Errcode HttpEntity::updateUser(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"user_id", "account", "name", "gender", "age", "phone", "email", "role_id"}, params);
2025-08-31 14:38:53 +08:00
return DAO::updateUserById(params);
}
Errcode HttpEntity::deleteUser(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
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)
2025-08-31 14:38:53 +08:00
{
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);
2025-09-12 18:44:34 +08:00
// 查询所有的角色权限关联
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);
}
}
}
}
2025-08-31 14:38:53 +08:00
return err;
}
Errcode HttpEntity::insertPermission(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"name", "describe", "is_open"}, params);
2025-08-31 14:38:53 +08:00
return DAO::insertPermission(params);
}
Errcode HttpEntity::updatePermission(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"permission_id", "name", "describe", "is_open"}, params);
2025-08-31 14:38:53 +08:00
return DAO::updatePermissionById(params);
}
Errcode HttpEntity::deletePermission(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
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)
2025-08-31 14:38:53 +08:00
{
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);
2025-09-12 18:44:34 +08:00
HttpHelper::setPagination(pageinfo, result, json);
2025-08-31 14:38:53 +08:00
// 查询所有的角色权限关联
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<int>> mapRole;
std::map<std::string, std::vector<int>> mapChildren;
for (int i=0; i<vecPermission.size(); ++i)
2025-08-31 14:38:53 +08:00
{
auto& item = vecPermission[i];
std::string roleId = item.value("role_id");
std::string parentId = item.value("parent_id");
mapRole[roleId].push_back(i);
if (parentId != "")
{
mapChildren[roleId + "-" + parentId].push_back(i);
}
2025-08-31 14:38:53 +08:00
}
for (auto& item : json["data"])
2025-08-31 14:38:53 +08:00
{
auto jsonpermission = njson::array();
std::string roleId = item["role_id"];
for (auto& fieldsPos : mapRole[roleId])
{
auto& fields = vecPermission[fieldsPos];
string parentId = fields.value("parent_id");
string permissionId = fields.value("permission_id");
if (parentId == "")
{
njson node;
FieldsToJson(fields, node);
njson nodeChildren = njson::array();
auto iter = mapChildren.find(roleId + "-" + permissionId);
if (iter != mapChildren.end())
{
for (auto& fieldsChildPos : iter->second)
{
njson nodeChild;
FieldsToJson(vecPermission[fieldsChildPos], nodeChild);
nodeChildren.push_back(nodeChild);
}
}
node["children"] = nodeChildren;
jsonpermission.push_back(node);
}
2025-08-31 14:38:53 +08:00
}
item["permission"] = jsonpermission;
2025-08-31 14:38:53 +08:00
}
}
return err;
}
2025-09-12 18:44:34 +08:00
Errcode HttpEntity::queryRolePermission(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"role_id"}, params);
2025-09-12 18:44:34 +08:00
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)
2025-08-31 14:38:53 +08:00
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"name", "describe", "is_open", "permission"}, params);
2025-08-31 14:38:53 +08:00
return DAO::insertRole(params);
};
static void JsonToFieldsRole(string roleId, njson& item, 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>());
}
Errcode HttpEntity::updateRole(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"role_id", "name", "describe", "is_open", "permission"}, params);
2025-09-05 19:44:26 +08:00
auto roleId = params.value("role_id");
2025-09-12 18:44:34 +08:00
std::string permission = params.remove("permission");
2025-09-05 19:44:26 +08:00
auto dao = DaoEntity::create("");
2025-09-12 18:44:34 +08:00
auto err = Errcode::OK;
if (params.size() > 1)
{
err = DAO::updateRoleById(dao, params);
}
if (err == Errcode::OK && !permission.empty())
2025-09-05 19:44:26 +08:00
{
2025-09-12 18:44:34 +08:00
njson jsonarray;
if (JSON::parse(permission, jsonarray))
2025-09-05 19:44:26 +08:00
{
2025-09-12 18:44:34 +08:00
std::vector<Fields> vecFields;
for (auto& item: jsonarray)
2025-09-05 19:44:26 +08:00
{
2025-09-12 18:44:34 +08:00
Fields fields;
JsonToFieldsRole(roleId, item, fields);
2025-09-12 18:44:34 +08:00
vecFields.push_back(fields);
if (item.contains("children"))
{
for (auto& item : item["children"])
{
Fields fields;
JsonToFieldsRole(roleId, item, fields);
vecFields.push_back(fields);
}
}
2025-09-05 19:44:26 +08:00
}
err = DAO::updateRolePermission(dao, roleId, vecFields);
}
}
return err;
2025-08-31 14:38:53 +08:00
};
Errcode HttpEntity::deleteRole(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
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)
2025-08-31 14:38:53 +08:00
{
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);
2025-12-01 18:26:42 +08:00
for (auto& item : result)
{
int stationId = item.get<int>("station_id");
auto station = Application::data().getStation(stationId);
if (station)
{
item.set("err", station->err);
}
}
2025-08-31 14:38:53 +08:00
HttpHelper::setPagination(pageinfo, result, json);
return err;
};
Errcode HttpEntity::insertStation(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"name", "address", "lon", "lat", "tel", "capacity", "status"}, params);
2025-08-31 14:38:53 +08:00
return DAO::insertStation(params);
};
Errcode HttpEntity::updateStation(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
Fields params;
2025-09-20 16:41:08 +08:00
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");
2025-09-19 18:54:36 +08:00
params.check("policy_id", "", "NULL");
2025-09-24 19:06:31 +08:00
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
{
2025-09-19 18:54:36 +08:00
auto station = Application::data().getStation(Utils::toInt(stationId));
if (result.size() > 0 && station)
{
2025-09-19 18:54:36 +08:00
station->setFields(result[0]);
}
}
}
2026-03-17 15:21:28 +08:00
// 发送指令到网关
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();
2026-03-17 15:21:28 +08:00
// 根据 work_mode 到数据库查询策略信息
std::string sql = std::format("select * from policy where `type`='{}'", workmode);
std::vector<Fields> result;
int ret = DaoEntity::execOnce(sql, result);
if (result.size() > 0)
{
auto& item = result[0];
std::string valJson = item.value("value");
njson json = njson::parse(valJson);
if (json.is_object())
{
// 设置 station 的网关参数,然后调用 setGarewayParams 向网关发送指令
if (workmode == 6)
{
if (json.contains("soc_min")) { station->gatewayParam.socMin = Utils::toFloat(json["soc_min"])*100; }
if (json.contains("soc_max")) { station->gatewayParam.socMax = Utils::toFloat(json["soc_max"])*100; }
}
else if (workmode == 7)
{
//if (json.contains("charge")) { station->gatewayParam.powerCharge = json["charge"].get<float>(); }
//if (json.contains("discharge")) { station->gatewayParam.powerDischarge = json["discharge"].get<float>(); }
}
else if (workmode == 8)
{
if (json.contains("charge")) { station->gatewayParam.powerCharge = Utils::toInt(json["charge"]); }
if (json.contains("discharge")) { station->gatewayParam.powerDischarge = Utils::toInt(json["discharge"]); }
if (json.contains("power_reverse")) { station->gatewayParam.backflow = Utils::toInt(json["power_reverse"]); }
}
else if (workmode == 9)
{
if (json.contains("charge")) { station->gatewayParam.powerCharge = Utils::toInt(json["charge"]); }
if (json.contains("discharge")) { station->gatewayParam.powerDischarge = Utils::toInt(json["discharge"]); }
}
}
//station->setGarewayParams();
}
////params.get("work_mode", station->workMode);
//ps.get("soc_min", station->gatewayParam.socMin); // 储能放电下限值 SOC 40038 (%, 0-99)
//ps.get("soc_max", station->gatewayParam.socMax); // 储能充电上限值 SOC 40039 (%:1-100)
//ps.get("capacity", station->gatewayParam.capacity); // 台区变压器容量 40040 (KVA 160-1600)
//ps.get("power_safe", station->gatewayParam.powerSafe); // 安全输入功率 40041 (KW 0-400)
//ps.get("power_discharge", station->gatewayParam.powerDischarge); // 储能最大放电功率 40042 (1KW 0-150)
//ps.get("power_charge", station->gatewayParam.powerCharge); // 储能最大充电功率 40043 (1KW 0-150)
//ps.get("backflow", station->gatewayParam.backflow); // 防逆流回差 40058(1KW 10-300)
//ps.get("overload", station->gatewayParam.overload); // 防过载回差 40059(1KW 10-300)
}
}
return err;
2025-08-31 14:38:53 +08:00
};
Errcode HttpEntity::deleteStation(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
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;
2025-09-20 16:41:08 +08:00
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, "count":0, "power":0.0})");
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 station = Application::data().getStation(Utils::toInt(stationId));
//if (station)
//{
// jsonStorage["msg"] = station->getGatewayParam();
// jsonStorage["workmode"] = station->getGatewayMode();
// jsonStorage["emu"] = station->emuStatus == 1 ? "在线" : (station->emuStatus == 0 ? "离线" : "--");
// jsonStorage["cdz"] = station->cdzStatus == 1 ? "在线" : (station->cdzStatus == 0 ? "离线" : "--");
//}
2025-09-19 18:54:36 +08:00
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)
2025-09-04 19:31:04 +08:00
{
// 查询场站的基础配置信息
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;
2025-09-04 19:31:04 +08:00
std::string attr = fields.remove(DMStation::ATTR);
JSON::parse(attr, jsondata);
2025-09-04 19:31:04 +08:00
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)
2025-09-04 19:31:04 +08:00
{
2025-09-19 18:54:36 +08:00
std::string stationId = req.get_param_value("station_id");
auto station = Application::data().getStation(Utils::toInt(stationId));
njson jsondata;
2025-09-19 18:54:36 +08:00
if (station)
{
/// 储能:电压、电流、功率、功率因数
{
njson json = njson::object();
json["U"] = Utils::toStr(station->storage.voltage);
json["I"] = Utils::toStr(station->storage.current);
json["P"] = Utils::toStr(station->storage.power);
//json["PF"] = Utils::toStr(station->storage.powerFactor, 1);
jsondata["storage"] = json;
}
/// 充电:电压、电流、功率、功率因数
{
njson json = njson::object();
json["U"] = Utils::toStr(station->charge.connector1.voltage);
json["I"] = Utils::toStr(station->charge.connector1.current);
json["P"] = Utils::toStr(station->charge.connector1.power);
jsondata["charge"] = json;
}
/// 光伏
{
njson json = njson::object();
json["P"] = Utils::toStr(station->pv.power);
jsondata["pv"] = json;
}
/// 电网
{
njson json = njson::object();
json["U"] = Utils::toStr(station->grid.voltage);
json["I"] = Utils::toStr(station->grid.current);
json["P"] = Utils::toStr(station->grid.power);
//json["PF"] = Utils::toStr(station->grid.powerFactor, 1);
jsondata["grid"] = json;
}
/// 环境:温度、湿度
{
njson json = njson::object();
json["envTemp"] = Utils::toStr(station->temperature, 0);
json["envhum"] = Utils::toStr(station->humidity, 0);
json["aircStatus"] = station->aircStatus;
json["coolingStatus"] = station->coolingStatus;
jsondata["env"] = json;
}
2025-09-19 18:54:36 +08:00
}
2025-09-04 19:31:04 +08:00
json["data"] = jsondata;
return Errcode::OK;
}
2025-08-31 14:38:53 +08:00
static njson VectorToJsonArray(vector<float>& vec, int n)
{
njson jsonArray = njson::array();
for (int i = 0; i <= n && i < vec.size(); ++i)
{
jsonArray.push_back(int(vec[i]));
}
return jsonArray;
}
// 获取场站今日电压曲线数据category: 1储能2充电3光伏
Errcode HttpEntity::queryStationTodayU(const httplib::Request& req, njson& json, std::string& errmsg)
{
std::string stationId = req.get_param_value("station_id");
std::string catogray = req.get_param_value("category");
njson jsondata;
auto station = Application::data().getStation(Utils::toInt(stationId));
if (station)
{
int n = Utils::timeDaySeconds() / 600;
if (catogray == "1")
{
2026-02-06 14:29:37 +08:00
auto device = station->getDeviceByType(int(EDeviceType::BMS), "1"); // 使用 BMS 的数据
if (device) {
jsondata["U"] = VectorToJsonArray(device->cacheU, n);
jsondata["I"] = VectorToJsonArray(device->cacheI, n);
jsondata["P"] = VectorToJsonArray(device->cacheP, n);
}
}
else if (catogray == "2")
{
auto device = station->getDeviceByType(int(EDeviceType::CHARGER), "1");
if (device) {
jsondata["U"] = VectorToJsonArray(device->cacheU, n);
jsondata["I"] = VectorToJsonArray(device->cacheI, n);
jsondata["P"] = VectorToJsonArray(device->cacheP, n);
}
}
else if (catogray == "3")
{
}
}
json["data"] = jsondata;
return Errcode::OK;
}
// 获取场站今日电流曲线数据category: 1储能2充电3光伏
Errcode HttpEntity::queryStationTodayI(const httplib::Request& req, njson& json, std::string& errmsg)
{
return Errcode::OK;
}
// 获取场站今日功率曲线数据category: 1储能2充电3光伏
Errcode HttpEntity::queryStationTodayP(const httplib::Request& req, njson& json, std::string& errmsg)
{
return Errcode::OK;
}
Errcode HttpEntity::queryDeviceList(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
string stationId = req.get_param_value("station_id");
2025-08-31 14:38:53 +08:00
std::vector<Fields> result;
auto err = DAO::queryDeviceListByStation(pageinfo, stationId, result);
2025-08-31 14:38:53 +08:00
HttpHelper::setPagination(pageinfo, result, json);
return err;
};
Errcode HttpEntity::insertDevice(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
2025-09-12 18:44:34 +08:00
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;
2025-08-31 14:38:53 +08:00
};
2025-09-12 18:44:34 +08:00
Errcode HttpEntity::updateDevice(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"device_id", "station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
2025-09-12 18:44:34 +08:00
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;
2025-08-31 14:38:53 +08:00
};
Errcode HttpEntity::deleteDevice(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
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)
2025-08-31 14:38:53 +08:00
{
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;
2025-09-20 16:41:08 +08:00
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);
2025-09-24 19:06:31 +08:00
if (station)
{
std::vector<std::shared_ptr<Device>> vecDevice;
2025-09-16 19:38:46 +08:00
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;
njson jsongateway = njson::object();
if (station)
{
jsongateway["msg"] = station->getGatewayParam();
jsongateway["workmode"] = station->getGatewayMode();
jsongateway["emu"] = station->emuStatus == 1 ? "在线" : (station->emuStatus == 0 ? "离线" : "--");
jsongateway["cdz"] = station->cdzStatus == 1 ? "在线" : (station->cdzStatus == 0 ? "离线" : "--");
jsongateway["soc_min"] = station->gatewayParam.socMin;
jsongateway["soc_max"] = station->gatewayParam.socMax;
jsongateway["capacity"] = station->gatewayParam.capacity;
jsongateway["power_safe"] = station->gatewayParam.powerSafe;
jsongateway["power_discharge"] = station->gatewayParam.powerDischarge;
jsongateway["power_charge"] = station->gatewayParam.powerCharge;
jsongateway["backflow"] = station->gatewayParam.backflow;
jsongateway["overload"] = station->gatewayParam.overload;
}
json["gateway"] = jsongateway;
return Errcode::OK;
}
Errcode HttpEntity::queryDevicCharts(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
2025-09-20 16:41:08 +08:00
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);
int npos = Utils::timeDaySeconds() / 600;
std::vector<int> vecU(npos, 0);
std::vector<int> vecI(npos, 0);
std::vector<int> vecP(npos, 0);
if (device)
{
for (size_t i = 0; i < npos; ++i)
{
if (i < device->cacheU.size()) vecU[i] = int(device->cacheU[i]);
if (i < device->cacheI.size()) vecI[i] = int(device->cacheI[i]);
if (i < device->cacheP.size()) vecP[i] = int(device->cacheP[i]);
}
}
json["data"] = {{"V", vecU}, {"I", vecI}, {"P", vecP}};
return Errcode::OK;
}
2025-08-31 14:38:53 +08:00
Errcode HttpEntity::queryDeviceBCUDetail(const httplib::Request& req, njson& json, std::string& errmsg)
{
2025-09-19 18:54:36 +08:00
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"station_id", "device_id"}, params);
2025-09-19 18:54:36 +08:00
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();
2025-09-19 18:54:36 +08:00
if (device)
{
2025-09-19 18:54:36 +08:00
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], 3);
2025-09-19 18:54:36 +08:00
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)
2025-08-31 14:38:53 +08:00
{
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)
2025-08-31 14:38:53 +08:00
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"type", "name", "describe", "value", "is_open"}, params);
2025-08-31 14:38:53 +08:00
return DAO::insertPolicy(params);
};
Errcode HttpEntity::updatePolicy(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
Fields params;
GetRequestParams(req, {"policy_id", "type", "name", "describe", "value", "is_open"}, params);
auto err = DAO::updatePolicyById(params);
if (err == Errcode::OK)
{
int policyId = params.get<int>("policy_id");
auto policy = Application::data().getPolicyById(policyId);
if (policy)
{
policy->setFields(params);
}
}
return err;
2025-08-31 14:38:53 +08:00
};
Errcode HttpEntity::deletePolicy(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
2025-09-05 19:44:26 +08:00
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"policy_id"}, params);
2025-09-05 19:44:26 +08:00
return DAO::deletePolicyById(params.value("policy_id"));
2025-08-31 14:38:53 +08:00
};
2025-09-19 18:54:36 +08:00
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);
json["data"] = FieldsToJsonArray(result);
2025-09-19 18:54:36 +08:00
return Errcode(ret);
}
2025-08-31 14:38:53 +08:00
Errcode HttpEntity::querySystemLogList(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
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)
2025-08-31 14:38:53 +08:00
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"log_id", "status"}, params);
2025-08-31 14:38:53 +08:00
return DAO::updateSystemLogById(params);
}
Errcode HttpEntity::queryAlertLogList(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
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)
2025-08-31 14:38:53 +08:00
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"log_id", "status"}, params);
2025-08-31 14:38:53 +08:00
return DAO::updateAlertLogById(params);
}
Errcode HttpEntity::queryPredictionDetail(const httplib::Request& req, njson& json, std::string& errmsg)
2025-08-31 14:38:53 +08:00
{
2025-09-22 20:01:41 +08:00
const int num = 144;
std::vector<int> vecStoreIn(num, 0), vecStoreOut(num, 0), vecCharge(num, 0), vecSolar(num, 0), vecSolarP(num, 0);
for (auto& item : Application::data().mapStation)
2025-08-31 14:38:53 +08:00
{
auto& station = item.second;
2025-12-01 18:26:42 +08:00
//auto station = Application::data().getStation(5);
for (int i = 0; i < num; ++i)
{
vecStoreIn[i] += station->predictStorageIn[i];
vecStoreOut[i] += station->predictStorageOut[i];
vecCharge[i] += station->predictCharge[i];
vecSolar[i] = 0;
vecSolarP[i] = 0;
}
2025-08-31 14:38:53 +08:00
}
json["data"] = {
{"W_store_in", vecStoreIn},
{"W_store_out", vecStoreOut},
{"W_charge", vecCharge},
{"W_solar", vecSolar},
{"P_solar", vecSolarP }
};
return Errcode::OK;
}
2025-09-16 19:38:46 +08:00
static void VerifyRequstParamsStatDate(Fields& params)
{
2025-09-16 19:38:46 +08:00
if (!params.contains("end_date"))
{
2025-09-16 19:38:46 +08:00
if (!params.contains("start_date"))
{
params.set("end_date", Utils::dateStr());
params.set("start_date", Utils::dateStr(Utils::date() - 86400 * 7));
2025-09-16 19:38:46 +08:00
}
else
{
params.set("end_date", Utils::dateStr(Utils::time(params.value("start_date") + " 00:00:00") + 86400 * 7));
2025-09-16 19:38:46 +08:00
}
}
}
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");
2025-09-04 19:31:04 +08:00
2025-09-16 19:38:46 +08:00
std::string sqlCondition;
if (!dtStart.empty() && dtEnd.empty())
{
sqlCondition += "dt BETWEEN '" + dtStart + "' AND '" + dtEnd + "'";
}
if (!stationId.empty())
2025-09-16 19:38:46 +08:00
{
if (!sqlCondition.empty()) sqlCondition += " AND ";
sqlCondition += "ss.station_id='" + stationId + "'";
}
if (!category.empty() && category != "0")
{
2025-09-24 19:06:31 +08:00
//if (!sqlCondition.empty()) sqlCondition += " AND ";
//sqlCondition += "ss.category='" + category + "'";;
2025-09-16 19:38:46 +08:00
}
if (!sqlCondition.empty()) { sqlCondition = " WHERE " + sqlCondition; }
return sqlCondition;
}
2025-09-19 18:54:36 +08:00
static std::string GetRequestStatParams(const httplib::Request& req, Fields& params)
{
GetRequestParams(req, { "station_id", "category", "start_date", "end_date" }, params);
2025-09-16 19:38:46 +08:00
VerifyRequstParamsStatDate(params);
return VerifyStatSqlCondition(params);
}
static string GetStationStatusStr(int status)
{
if (status == 1) return "空闲";
else if (status == 2) return "充电";
else if (status == 2) return "放电";
else if (status == 9) return "故障";
else return "离线";
}
2025-09-16 19:38:46 +08:00
Errcode HttpEntity::queryStatTotal(const httplib::Request& req, njson& json, std::string& errmsg)
{
2025-09-19 18:54:36 +08:00
Fields params;
std::string sqlCondition = GetRequestStatParams(req, params);
njson jsondata;
std::string launchDate;
float incomeTotal{};
int storageDeviceNum = 0;
int chargeDeviceNum = 0;
int solarDeviceNum = 0;
int capacityTotal{};
bool isQueryStation = params.contains("station_id");
if (isQueryStation)
{
std::string stationId = params.value("station_id");
auto station = Application::data().getStation(Utils::toInt(stationId));
if (station)
{
launchDate = station->launchDate;
storageDeviceNum = 1; //: 储能设备数量
chargeDeviceNum = station->getDeviceCount(2); //: 光伏设备数量
solarDeviceNum = station->getDeviceCount(3); //: 光伏设备数量
capacityTotal = station->capacity; // : 储能总容量kWh精度0.001
jsondata["storage_status"] = GetStationStatusStr(station->storage.status);
jsondata["charge_status"] = GetStationStatusStr(station->charge.status);
jsondata["pv_status"] = "离线";
}
}
else
2025-09-19 18:54:36 +08:00
{
auto& appdata = Application::data();
launchDate = appdata.launchDate; //: 系统上线启用日期格式yyyy-mm-dd
for (auto& item : appdata.mapStation)
{
auto& station = item.second;
storageDeviceNum += 1;
chargeDeviceNum += station->getDeviceCount(2);
solarDeviceNum += station->getDeviceCount(3);
capacityTotal += station->capacity;
}
2025-09-19 18:54:36 +08:00
}
jsondata["launch_date"] = launchDate; // 场站上线启用日期格式yyyy-mm-dd
jsondata["storage_device_num"] = storageDeviceNum; //: 储能设备数量
jsondata["charge_device_num"] = chargeDeviceNum; //: 储能设备数量
jsondata["income_total"] = incomeTotal; // : 累计收益精度0.01
jsondata["solar_device_num"] = solarDeviceNum; //: 光伏设备数量
jsondata["capacity_total"] = capacityTotal; // : 储能总容量kWh精度0.001
2025-09-16 19:38:46 +08:00
// 从 stat_total 表中查询日期最新的一条数据
2025-09-16 19:38:46 +08:00
std::vector<Fields> result;
std::string sql = std::format("SELECT st.* FROM stat_total st INNER JOIN "
2025-12-01 18:26:42 +08:00
"(SELECT station_id, MAX(dt) max_dt FROM stat_total ss {} GROUP BY station_id) tmp "
"ON st.station_id = tmp.station_id AND st.dt = tmp.max_dt; ", sqlCondition);
2025-09-16 19:38:46 +08:00
DaoEntity::execOnce(sql, result);
int eIn = 0;
int eOut = 0;
int tIn = 0;
int tOut = 0;
int nErr = 0;
int eGen = 0;
int eGrid = 0;
int eCharge = 0;
int income = 0;
int incomeCharge = 0;
for (int i=0; i<result.size(); ++i)
{
auto& fields = result[i];
if (isQueryStation)
{
if (params.value("station_id") == fields.value("station_id"))
{
eIn = fields.get<int>("E_in");
eOut = fields.get<int>("E_out");
tIn = fields.get<int>("t_in");
tOut = fields.get<int>("t_out");
eGen = fields.get<int>("E_gen");
eGrid = fields.get<int>("E_grid");
eCharge = fields.get<int>("E_charge");
income = fields.get<int>("income");
}
}
else
{
eIn += fields.get<int>("E_in");
eOut += fields.get<int>("E_out");
tIn += fields.get<int>("t_in");
tOut += fields.get<int>("t_out");
eGen += fields.get<int>("E_gen");
eGrid = fields.get<int>("E_grid");
eCharge += fields.get<int>("E_charge");
income += fields.get<int>("income");
}
}
jsondata["storage_elect_in"] = eIn; //储能充电电量kWh精度0.001
jsondata["storage_elect_out"] = eOut; //储能放电电量kWh精度0.001
jsondata["storage_num_in"] = tIn; //储能设备充电次数
jsondata["storage_num_out"] = tOut; //储能设备放电次数
//jsondata["storage_num_err"] = fields.value("n_err"); //储能设备故障次数
jsondata["solar_elect_gen"] = eGen; //光伏发电电量kWh精度0.001
jsondata["solar_elect_grid"] = eGrid; //光伏入网电量kWh精度0.001
//jsondata["solar_num_err"] = fields.value("n_err_solor"); //光伏设备故障次数
jsondata["charge_elect"] = eCharge; //充电设备充电电量kWh精度0.001
//jsondata["charge_num"] = fields.value("n_charge"); //充电设备充电次数
//jsondata["charge_num_err"] = fields.value("n_err_charge"); //充电设备故障次数
jsondata["income_elect"] = income; //发电收益精度0.01
//jsondata["income_charge"] = fields.value("income_charge"); //充电收益精度0.01
//jsondata["usage_rate"] = 0; //Utils::toStr(float(fields.get<int>("storage_usage") + fields.get<int>("storage_usage")) * 0.5f, 0);
json["data"] = jsondata;
return Errcode::OK;
}
Errcode HttpEntity::queryStatSystem(const httplib::Request& req, njson& json, std::string& errmsg)
{
auto& appdata = Application::data();
float income = 0.0;
int nStation = 0;
int nSolar {};
int capacity {};
int eGen {};
int eGrid {};
int eIn {};
int eOut {};
for (auto& item : appdata.mapStation)
{
auto& station = item.second;
nStation += 1;
nSolar += station->getDeviceCount(3);
capacity += station->capacity;
eGen += station->electGenTotal;
eGrid += station->electGridTotal;
eIn += station->statData.totalElectIn;
eOut += station->statData.totalElectOut;
}
2025-09-12 18:44:34 +08:00
njson jsondata;
jsondata["launch_date"] = appdata.launchDate; //: 系统上线启用日期格式yyyy-mm-dd
jsondata["income_total"] = income; // : 累计收益精度0.01
jsondata["storage_device_num"] = nStation; //: 储能设备数量
jsondata["solar_device_num"] = nSolar; //: 光伏设备数量
jsondata["capacity_total"] = capacity; // : 储能总容量kWh精度0.001
jsondata["solar_elect_gen"] = eGen; // : 发电总电量kWh精度0.001
jsondata["solar_elect_grid"] = eGrid; // : 入网总电量kWh精度0.001
jsondata["storage_elect_in"] = eIn; // : 储能充电总电量kWh精度0.001
jsondata["storage_elect_out"] = eOut; // : 储能放电总电量kWh精度0.001
// 总览页面:累计收益
std::string sql = "SELECT st.* FROM stat_total st INNER JOIN "
"(SELECT station_id, MAX(dt) max_dt FROM stat_total GROUP BY station_id) tmp "
"ON st.station_id = tmp.station_id AND st.dt = tmp.max_dt; ";
std::vector<Fields> result;
DAO::exec(NULL, sql, result);
for (auto& item: result)
{
income += item.get<float>("income");
}
jsondata["income_total"] = income;
json["data"] = jsondata;
2025-09-16 19:38:46 +08:00
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.name station_name, st.* FROM stat_total st INNER JOIN
(SELECT station_id, MAX(dt) max_dt FROM stat_total GROUP BY station_id) tmp
ON st.station_id=tmp.station_id AND st.dt=tmp.max_dt
LEFT JOIN station s ON s.station_id=st.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");
jsonnode["usage_rate"] = fields.get<float>("usage");
jsondata.push_back(jsonnode);
}
json["data"] = jsondata;
return Errcode(err);
}
2025-09-16 19:38:46 +08:00
Errcode HttpEntity::queryStatDayList(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"station_id", "category", "start_date", "end_date"}, params);
2025-09-16 19:38:46 +08:00
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");
2025-09-19 18:54:36 +08:00
if (endDate.empty())
{
int64_t t = Utils::time();
endDate = Utils::dateStr(t);
startDate = Utils::dateStr(t - 86400*7);
}
2025-09-12 18:44:34 +08:00
std::vector<Fields> result;
2025-09-16 19:38:46 +08:00
auto err = DAO::queryStatStationGroup(NULL, stationId, category, startDate, endDate, result);
2025-09-19 18:54:36 +08:00
if (!startDate.empty() && !endDate.empty())
{
std::map<std::string, Fields*> mapTemp;
for (auto& item: result)
{
auto& dt = item.value("dt");
mapTemp[dt] = &item;
}
2025-09-19 18:54:36 +08:00
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)
{
i++;
2025-09-19 18:54:36 +08:00
njson jsonrow;
std::string dt = Utils::dateStr(t);
Fields* fields = NULL;
auto iter = mapTemp.find(dt);
if (iter != mapTemp.end()) { fields = iter->second; }
2025-09-19 18:54:36 +08:00
jsonrow["dt"] = dt.substr(5);
jsonrow["storage_elect_in"] = fields ? fields->value("storage_elect_in") : "0";
2025-09-19 18:54:36 +08:00
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";
2025-09-19 18:54:36 +08:00
jsondata.push_back(jsonrow);
}
json["data"] = jsondata;
}
else
{
json["data"] = FieldsToJsonArray(result);
}
2025-09-12 18:44:34 +08:00
return err;
2025-09-16 19:38:46 +08:00
}
2025-09-12 18:44:34 +08:00
2025-09-16 19:38:46 +08:00
//Errcode HttpEntity::queryStatDayList(const httplib::Request& req, njson& json, std::string& errmsg)
//{
// std::string sqlCondition = GetRequestStatParams(req);
2025-09-19 18:54:36 +08:00
// std::string sql = R"(SELECT ss.*, d.name device_name, ddt.name device_type FROM stat_day ss
2025-09-16 19:38:46 +08:00
// 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;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"station_id", "category", "start_date", "end_date"}, params);
2025-09-16 19:38:46 +08:00
std::vector<Fields> result;
auto err = DAO::queryStatStationList(pageinfo, params, result);
2025-09-19 18:54:36 +08:00
//json["data"] = FieldsToJsonArray(result);
HttpHelper::setPagination(pageinfo, result, json);
2025-09-16 19:38:46 +08:00
return err;
2025-09-04 19:31:04 +08:00
}
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; }
2025-09-12 18:44:34 +08:00
if (dt.empty()) { dt=Utils::dateStr(); }
njson jsondata;
2026-02-06 14:29:37 +08:00
std::string sql = R"(SELECT hd.*, d.`type` device_type, d.code, 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)
2026-02-06 14:29:37 +08:00
int deviceType = fields.get<int>("device_type");
int deviceCode = fields.get<int>("code");
if (category == "1")
{
if (!(deviceType == int(EDeviceType::BMS))) // 储能BMS储能设备以BMS电池的数据作为总数据来展示
{
continue;
}
}
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;
}
2025-09-20 16:41:08 +08:00
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";
2025-09-24 19:06:31 +08:00
sql += " WHERE sd.station_id = '" + stationId + "' AND category = '" + category + "'";
sql += " AND dt BETWEEN '" + startDate + "' AND '" + endDate + "2025-09-19' AND sd.category = '1'";
2025-09-20 16:41:08 +08:00
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)
2025-09-04 19:31:04 +08:00
{
std::string stationId = req.get_param_value("station_id");
auto& appdata = Application::data();
2025-09-04 19:31:04 +08:00
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;
2025-09-04 19:31:04 +08:00
{ // 温湿度
auto& mapTempHumUnit = station->mapTempHumUnit;
njson nodearray = njson::array();
2025-09-04 19:31:04 +08:00
for (auto iter = mapTempHumUnit.begin(); iter!=mapTempHumUnit.end(); iter++)
{
auto& unit = iter->second;
njson node;
2025-09-04 19:31:04 +08:00
node["pos"] = "#" + std::to_string(iter->first);
2025-09-19 18:54:36 +08:00
node["temp"] = Utils::toStr(unit.temp);
node["hum"] = Utils::toStr(unit.hum);
2025-09-04 19:31:04 +08:00
nodearray.push_back(node);
}
jsondata["temp_hum"] = nodearray;
}
{ //空调
auto& mapAircUnit = station->mapAircUnit;
njson nodearray = njson::array();
2025-09-19 18:54:36 +08:00
for (auto& item: mapAircUnit)
2025-09-04 19:31:04 +08:00
{
2025-09-19 18:54:36 +08:00
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;
2025-09-04 19:31:04 +08:00
}
jsondata["airc"] = nodearray;
}
{ // 消防
static std::map<int, std::string> mapFireStatusDef = { {0, "正常"}, {1,"预警"}, {2,"火警"} };
2025-09-16 19:38:46 +08:00
std::map<int, string> mapStatusDef = {{0, "无效"}, {1, "掉线"}, {2, "正常"}, {3, "启动"}};
2025-09-04 19:31:04 +08:00
auto& mapFire40Unit = station->mapFire40Unit;
njson nodearray = njson::array();
2025-09-04 19:31:04 +08:00
for (auto iter = mapFire40Unit.begin(); iter!=mapFire40Unit.end(); ++iter)
{
2025-09-16 19:38:46 +08:00
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;
2025-09-04 19:31:04 +08:00
}
jsondata["fire40"] = nodearray;
}
{ // 冷机
auto& mapCoolingUnit = station->mapCoolingUnit;
njson nodearray = njson::array();
2025-09-19 18:54:36 +08:00
for (auto& item: mapCoolingUnit)
2025-09-04 19:31:04 +08:00
{
2025-09-19 18:54:36 +08:00
auto& unit = item.second;
njson node;
2025-09-19 18:54:36 +08:00
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 ? "正常" : "告警"}});
2025-09-04 19:31:04 +08:00
}
jsondata["cooling"] = nodearray;
}
json["data"] = jsondata;
2025-08-31 14:38:53 +08:00
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;
2025-09-20 16:41:08 +08:00
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;
2025-09-20 16:41:08 +08:00
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;
2025-09-20 16:41:08 +08:00
GetRequestParams(req, {"api_id"}, params);
return DAO::remove(NULL, "serviceapi", "api_id", params.value("api_id"));
}
Errcode HttpEntity::updateGatewayParams(const httplib::Request& req, njson& json, std::string& errmsg)
{
//上下限SOC安全输入功率储能最大充放电功率防逆流防过载回差。
Fields params;
GetRequestParams(req, {"station_id", "work_mode", "soc_min", "soc_max", "capacity", "power_safe", "power_discharge", "power_charge", "backflow", "overload"}, params);
int stationId = params.get<int>("station_id");
auto station = Application::data().getStation(stationId);
if (params.contains("work_mode"))
{
int workMode = params.get<int>("work_mode");
Fields fields;
fields.set("station_id", params.value("station_id"));
fields.set("work_mode", workMode);
Errcode err = DAO::updateStationById(params);
}
if (station)
{
2025-10-11 19:30:15 +08:00
//params.get("work_mode", station->workMode);
params.get("soc_min", station->gatewayParam.socMin); // 储能放电下限值 SOC 40038 (%, 0-99)
params.get("soc_max", station->gatewayParam.socMax); // 储能充电上限值 SOC 40039 (%:1-100)
params.get("capacity", station->gatewayParam.capacity); // 台区变压器容量 40040 (KVA 160-1600)
params.get("power_safe", station->gatewayParam.powerSafe); // 安全输入功率 40041 (KW 0-400)
params.get("power_discharge", station->gatewayParam.powerDischarge); // 储能最大放电功率 40042 (1KW 0-150)
params.get("power_charge", station->gatewayParam.powerCharge); // 储能最大充电功率 40043 (1KW 0-150)
params.get("backflow", station->gatewayParam.backflow); // 防逆流回差 40058(1KW 10-300)
params.get("overload", station->gatewayParam.overload); // 防过载回差 40059(1KW 10-300)
2025-10-11 19:30:15 +08:00
station->setGarewayParams();
return Errcode::OK;
}
return Errcode::ERR_PARAM;
2026-03-03 15:51:49 +08:00
}
static float SetPeriodRowJson(njson& jsonrow, std::string period, int eIn, int eOut, float priceIn, float priceOut, std::string dt)
{
jsonrow["dt"] = dt;
jsonrow["period"] = period;
jsonrow["E_in"] = eIn;
jsonrow["E_out"] = eOut;
jsonrow["grid_price"] = Utils::toStr(priceIn);
jsonrow["charge_price"] = Utils::toStr(priceOut);
return eOut * priceOut - eIn * priceIn;
}
Errcode HttpEntity::queryEGridPeriod(const httplib::Request& req, njson& json, std::string& errmsg)
{
Fields params;
GetRequestParams(req, {"dt", "station_id"}, params);
int stationId = params.get<int>("station_id");
std::string dt = params.value("dt");
//int year = 0;
//int month = 0;
//int day = 0;
//int ret = sscanf(date.c_str(), "%d-%d-%d", &year, &month, &day); // 解析3个值成功返回3
//if (ret != 3)
//{
// return Errcode::ERR_PARAM;
//}
if (stationId == 0 || dt.empty())
{
return Errcode::ERR_PARAM;
}
float priceJ = 0.0;
float priceF = 0.0;
float priceP = 0.0;
float priceG = 0.0;
float priceC = 0.0;
std::vector<Fields> result;
auto err = DAO::exec(NULL, "select * from egrid_price;", result);
if (err != Errcode::OK)
{
return err;
}
if (result.size() > 0)
{
for (auto& item: result)
{
int etype = item.get<int>("etype");
float price = item.get<float>("price", 2);
if (etype == 1) { priceG = price; }
else if (etype == 2) { priceP = price; }
else if (etype == 3) { priceF = price; }
else if (etype == 4) { priceJ = price; }
2026-03-03 15:51:49 +08:00
else if (etype == 9) { priceC = price; }
}
}
//std::string sql = std::format("SELECT ep.*, ep2.price FROM egrid_period ep LEFT JOIN egrid_price ep2 ON ep.etype=ep2.etype WHERE ep.`month`={};", month);
std::string sql = std::format("select * from stat_total_day WHERE dt='{}' AND station_id='{}';", dt, stationId);
err = DAO::exec(NULL, sql, result);
if (err != Errcode::OK)
{
return err;
}
njson jsondata = njson::array();
if (result.size() > 0)
{
auto& item = result[0];
float incomeTotal = 0.0f;
// 谷
{
njson jsonrow;
float income = SetPeriodRowJson(jsonrow, "", item.get<int>("E_in_G"), item.get<int>("E_out_G"), priceG, priceC, dt);
jsonrow["income"] = Utils::toStr(income);
jsondata.push_back(jsonrow);
incomeTotal += income;
}
// 平
{
njson jsonrow;
float income = SetPeriodRowJson(jsonrow, "", item.get<int>("E_in_P"), item.get<int>("E_out_P"), priceP, priceC, dt);
jsonrow["income"] = Utils::toStr(income);
jsondata.push_back(jsonrow);
incomeTotal += income;
}
// 峰
{
njson jsonrow;
float income = SetPeriodRowJson(jsonrow, "", item.get<int>("E_in_F"), item.get<int>("E_out_F"), priceF, priceC, dt);
jsonrow["income"] = Utils::toStr(income);
jsondata.push_back(jsonrow);
incomeTotal += income;
}
// 尖
{
njson jsonrow;
float income = SetPeriodRowJson(jsonrow, "", item.get<int>("E_in_J"), item.get<int>("E_out_J"), priceJ, priceC, dt);
jsonrow["income"] = Utils::toStr(income);
jsondata.push_back(jsonrow);
incomeTotal += income;
}
// 总计
{
njson jsonrow;
jsonrow["dt"] = dt;
jsonrow["period"] = "总计";
jsonrow["E_in"] = item.get<int>("E_in");
jsonrow["E_out"] = item.get<int>("E_out");
jsonrow["grid_price"] = "";
jsonrow["charge_price"] = "";
jsonrow["income"] = Utils::toStr(incomeTotal);
jsondata.push_back(jsonrow);
}
}
json["data"] = jsondata;
return Errcode::OK;
2025-08-31 14:38:53 +08:00
}