mirror of
https://gitee.com/js-yhsec/energy_storage.git
synced 2026-05-27 18:59:26 +08:00
完成系统管理web端功能,实现系统管理服务端接口,实现登录功能
This commit is contained in:
18
src/app/Admin.cpp
Normal file
18
src/app/Admin.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "Admin.h"
|
||||
#include "app/Dao.h"
|
||||
#include "common/Logger.h"
|
||||
|
||||
Errcode Admin::longin(std::string username, std::string passwd)
|
||||
{
|
||||
std::string err;
|
||||
Errcode ecode = DAO::login(nullptr, username, passwd, err);
|
||||
if (ecode != Errcode::OK)
|
||||
{
|
||||
XLOGE() << "login error, username=" << username << ", err=" << err;
|
||||
}
|
||||
else
|
||||
{
|
||||
XLOGE() << "login success, username=" << username;
|
||||
}
|
||||
return ecode;
|
||||
}
|
||||
16
src/app/Admin.h
Normal file
16
src/app/Admin.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "app/errcode.h"
|
||||
|
||||
class Admin
|
||||
{
|
||||
public:
|
||||
static Admin& instance()
|
||||
{
|
||||
static Admin admin;
|
||||
return admin;
|
||||
}
|
||||
|
||||
Errcode longin(std::string username, std::string pwd);
|
||||
};
|
||||
@@ -2,20 +2,68 @@
|
||||
|
||||
#include "common/Utils.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include "app/Dao.h"
|
||||
#include "app/Device.h"
|
||||
|
||||
void Application::init()
|
||||
{
|
||||
std::thread([=]()
|
||||
{
|
||||
while (!isQuit()) { runThreadMain(); }
|
||||
}).detach();
|
||||
Config::init("assets/config/app.json");
|
||||
|
||||
// 设置数据库配置
|
||||
DaoEntity::setOption(Config::option.database.host,
|
||||
Config::option.database.port,
|
||||
Config::option.database.user,
|
||||
Config::option.database.passwd,
|
||||
Config::option.database.dbname);
|
||||
XLOGI() << "[APP] set database option: host=" << Config::option.database.host
|
||||
<< ", port=" << Config::option.database.port
|
||||
<< ", user=" << Config::option.database.user
|
||||
<< ", dbname=" << Config::option.database.dbname;
|
||||
|
||||
// 连接数据库,读取基础信息
|
||||
|
||||
|
||||
// 读取设备信息,连接设备
|
||||
this->initDevice();
|
||||
std::thread([=]() { runThreadDevice(); }).detach();
|
||||
|
||||
// 创建主业务循环线程
|
||||
std::thread([=]() { runThreadMain(); }).detach();
|
||||
}
|
||||
|
||||
void Application::initDevice()
|
||||
{
|
||||
DaoEntity dao("");
|
||||
std::string sql = "select * from device;";
|
||||
vector<DataFields> result;
|
||||
dao.exec(sql, result);
|
||||
for (auto& fields: result)
|
||||
{
|
||||
Device::add(fields);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::runThreadMain()
|
||||
{
|
||||
static TimeTick tt;
|
||||
tt.elapse(1000);
|
||||
while (!isQuit())
|
||||
{
|
||||
|
||||
//XLOGD() << "HelloWorld";
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Application::runThreadDevice()
|
||||
{
|
||||
while (!isQuit())
|
||||
{
|
||||
|
||||
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
}
|
||||
@@ -15,11 +15,16 @@ public:
|
||||
}
|
||||
|
||||
void init();
|
||||
void initDevice();
|
||||
|
||||
bool isQuit() { return isQuit_; }
|
||||
Operator& getOperator() { return op_; }
|
||||
|
||||
void runThreadMain();
|
||||
|
||||
|
||||
void runThreadDevice();
|
||||
|
||||
private:
|
||||
bool isQuit_ = false;
|
||||
|
||||
|
||||
38
src/app/Config.cpp
Normal file
38
src/app/Config.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "Config.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "common/JsonN.h"
|
||||
#include "Logger.h"
|
||||
|
||||
AppOption Config::option;
|
||||
|
||||
bool Config::init(std::string filename)
|
||||
{
|
||||
NJson jsonroot;
|
||||
bool ret = NJsonLoad(filename, jsonroot);
|
||||
if (!ret)
|
||||
{
|
||||
XLOGE() << "[APP] load config failed, filename=" << filename;
|
||||
return false;
|
||||
}
|
||||
XLOGI() << "[APP] load config success, filename=" << filename;
|
||||
|
||||
if (jsonroot.contains("database"))
|
||||
{
|
||||
NJson json = jsonroot.at("database");
|
||||
option.database.host = json.contains("host") ? json.at("host") : "";
|
||||
option.database.port = json.contains("port") ? json.at("port") : 0;
|
||||
option.database.user = json.contains("user") ? json.at("user") : "";
|
||||
option.database.passwd = json.contains("passwd") ? json.at("passwd") : "";
|
||||
option.database.dbname = json.contains("dbname") ? json.at("dbname") : "";
|
||||
|
||||
XLOGI() << "[APP] load database config end. host=" << option.database.host;
|
||||
}
|
||||
else
|
||||
{
|
||||
XLOGI() << "[APP] load database config error: not found. host=" << option.database.host;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
26
src/app/Config.h
Normal file
26
src/app/Config.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
struct DatabaseOption
|
||||
{
|
||||
std::string host;
|
||||
int port;
|
||||
std::string user;
|
||||
std::string passwd;
|
||||
std::string dbname;
|
||||
};
|
||||
|
||||
struct AppOption
|
||||
{
|
||||
DatabaseOption database;
|
||||
};
|
||||
|
||||
class Config
|
||||
{
|
||||
public:
|
||||
static bool init(std::string filename);
|
||||
|
||||
|
||||
static AppOption option;
|
||||
};
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "common/Utils.h"
|
||||
#include "common/Snowflake.h"
|
||||
|
||||
|
||||
|
||||
enum class EnDatabaseErr
|
||||
{
|
||||
SUCCESS = 0,
|
||||
@@ -13,7 +15,7 @@ std::shared_ptr<DaoEntity> DAO::get(std::string tableName)
|
||||
return std::make_shared<DaoEntity>(tableName);
|
||||
}
|
||||
|
||||
bool DAO::login(std::shared_ptr<DaoEntity> dao, std::string account, std::string passwd, std::string& err)
|
||||
Errcode DAO::login(std::shared_ptr<DaoEntity> dao, std::string account, std::string passwd, std::string& err)
|
||||
{
|
||||
std::string t = Utils::timeNowStr();
|
||||
if (!dao)
|
||||
@@ -24,7 +26,7 @@ bool DAO::login(std::shared_ptr<DaoEntity> dao, std::string account, std::string
|
||||
{
|
||||
err = "数据库连接错误";
|
||||
DAO::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
|
||||
return false;
|
||||
return Errcode::ERR_DB_CONN;
|
||||
}
|
||||
|
||||
std::string sql = "SELECT * FROM user WHERE account='" + account + "';";
|
||||
@@ -35,24 +37,24 @@ bool DAO::login(std::shared_ptr<DaoEntity> dao, std::string account, std::string
|
||||
{
|
||||
err = "数据库操作错误";
|
||||
DAO::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
|
||||
return false;
|
||||
return Errcode::ERR_DB_CONN;
|
||||
}
|
||||
if (res.size() <=0)
|
||||
{
|
||||
err = "用户不存在";
|
||||
DAO::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
|
||||
return false;
|
||||
return Errcode::ERR_LOGIN_USER_NOTEXIST;
|
||||
}
|
||||
DataFields& fields = res[0];
|
||||
std::string userId = fields.get_str("user_id");
|
||||
int loginCount = fields.get_int("login_count");
|
||||
std::string userId = fields.getStr("user_id");
|
||||
int loginCount = fields.getInt("login_count");
|
||||
|
||||
// 判断密码
|
||||
if (passwd != fields.get_str("passwd"))
|
||||
if (passwd != fields.getStr("passwd"))
|
||||
{
|
||||
err = "密码错误";
|
||||
DAO::writeSystemLog(dao, 2, userId, account, "用户登录失败:" + err);
|
||||
return false;
|
||||
return Errcode::ERR_LOGIN_PASSWD;
|
||||
}
|
||||
|
||||
err = "登录成功";
|
||||
@@ -66,7 +68,7 @@ bool DAO::login(std::shared_ptr<DaoEntity> dao, std::string account, std::string
|
||||
}
|
||||
|
||||
DAO::writeSystemLog(dao, 2, userId, account, "用户登录成功");
|
||||
return true;
|
||||
return Errcode::OK;
|
||||
}
|
||||
|
||||
bool DAO::writeSystemLog(std::shared_ptr<DaoEntity> dao, int type, std::string userId, std::string account, std::string text)
|
||||
@@ -83,12 +85,12 @@ bool DAO::writeSystemLog(std::shared_ptr<DaoEntity> dao, int type, std::string u
|
||||
// 数据库写入登录日志
|
||||
dao->setTableName("system_log");
|
||||
DataFields fieldsLog;
|
||||
fieldsLog.set("id", Snowflake::instance().nextIdStr());
|
||||
fieldsLog.set("log_id", Snowflake::instance().getIdStr());
|
||||
fieldsLog.set("type", 2);
|
||||
fieldsLog.set("user_id", userId);
|
||||
fieldsLog.set("user_account", account);
|
||||
fieldsLog.set("content", text);
|
||||
fieldsLog.set("log_time", Utils::timeNowStr());
|
||||
fieldsLog.set("create_time", Utils::timeNowStr());
|
||||
bool ret = dao->insertFields({fieldsLog});
|
||||
return ret;
|
||||
}
|
||||
@@ -114,7 +116,7 @@ int DAO::insertUser(DataFields& fields)
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string account = fields.get_str("account");
|
||||
std::string account = fields.getStr("account");
|
||||
|
||||
// step1: 查询
|
||||
std::vector<DataFields> res;
|
||||
@@ -128,7 +130,7 @@ int DAO::insertUser(DataFields& fields)
|
||||
return 1;
|
||||
}
|
||||
|
||||
fields.set("user_id", Snowflake::instance().nextIdStr());
|
||||
fields.set("user_id", Snowflake::instance().getIdStr());
|
||||
fields.set("create_time", Utils::timeNowStr());
|
||||
ret = dao->insertFields(fields);
|
||||
return (ret) ? 0 : 1;
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#include "database/DaoEntity.h"
|
||||
|
||||
#include "app/errcode.h"
|
||||
|
||||
class DAO
|
||||
{
|
||||
public:
|
||||
static std::shared_ptr<DaoEntity> get(std::string tableName="");
|
||||
|
||||
static bool login(std::shared_ptr<DaoEntity> dao, std::string account, std::string passwd, std::string& err);
|
||||
static Errcode login(std::shared_ptr<DaoEntity> dao, std::string account, std::string passwd, std::string& err);
|
||||
|
||||
static bool writeSystemLog(std::shared_ptr<DaoEntity> dao, int type, std::string userId, std::string account, std::string text);
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
#include "Device.h"
|
||||
|
||||
#include "common/Logger.h"
|
||||
#include "common/Utils.h"
|
||||
#include "protocol/Communicator.h"
|
||||
#include "common/JsonN.h"
|
||||
|
||||
//int DeviceEntity::getAttrInt(std::string key)
|
||||
//{
|
||||
// auto iter = mapAttrs.find(key);
|
||||
// if (iter == mapAttrs.end()) { return 0; }
|
||||
// return Utils::toInt(iter->second);
|
||||
//}
|
||||
//
|
||||
//float DeviceEntity::getAttrFloat(std::string key)
|
||||
//{
|
||||
// auto iter = mapAttrs.find(key);
|
||||
// if (iter == mapAttrs.end()) { return 0.0f; }
|
||||
// return Utils::toFloat(iter->second);
|
||||
//}
|
||||
//
|
||||
//double DeviceEntity::getAttrDouble(std::string key)
|
||||
//{
|
||||
// auto iter = mapAttrs.find(key);
|
||||
// if (iter == mapAttrs.end()) { return 0.0; }
|
||||
// return Utils::toDouble(iter->second);
|
||||
//}
|
||||
//
|
||||
//std::string DeviceEntity::getAttrStr(std::string key)
|
||||
//{
|
||||
// auto iter = mapAttrs.find(key);
|
||||
// if (iter == mapAttrs.end()) { return ""; }
|
||||
// return iter->second;
|
||||
//}
|
||||
|
||||
int DeviceEntity::startComm()
|
||||
{
|
||||
if (!isOpen)
|
||||
{
|
||||
if (commEntity && commEntity->isAlive())
|
||||
{
|
||||
commEntity->close();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 从属性列表中获取通讯方式和通讯地址、端口
|
||||
std::string commType = attrs.getStr("commType");
|
||||
|
||||
// 如果entity的通讯协议类型当前配置不一致,需要关闭连接删除通讯后创建新的通讯
|
||||
if (commEntity && commEntity->type != commType)
|
||||
{
|
||||
commEntity->close();
|
||||
commEntity = nullptr;
|
||||
}
|
||||
// 创建新的通讯
|
||||
if (!commEntity)
|
||||
{
|
||||
commEntity = Communicator::createEntity(attrs);
|
||||
if (!commEntity) { return -1; }
|
||||
}
|
||||
|
||||
commEntity->start();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
// $$Device
|
||||
std::map<int, std::shared_ptr<DeviceEntity>> Device::mapDevices;
|
||||
|
||||
void Device::add(DataFields& fields)
|
||||
{
|
||||
auto entity = std::make_shared<DeviceEntity>();
|
||||
entity->deviceId = fields.getInt("device_id");
|
||||
entity->type = fields.getInt("type");
|
||||
entity->name = fields.getStr("name");
|
||||
entity->code = fields.getStr("code");
|
||||
entity->isOpen = fields.getInt("is_open");
|
||||
entity->attrsJson = fields.getStr("attrs");
|
||||
|
||||
// 解析属性的JSON字符串,转换成键值对
|
||||
NJson jsonroot;
|
||||
bool ret = NJsonParse(entity->attrsJson, jsonroot);
|
||||
if (!ret) // 解析错误
|
||||
{
|
||||
XLOGE() << "device attr json parse error, device_id=" << entity->deviceId;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto& [key, val] : jsonroot.items()) {
|
||||
std::string valType = val.type_name();
|
||||
if (valType == "string") {
|
||||
entity->attrs.set(key, val.get<std::string>());
|
||||
}
|
||||
else if (valType == "number") {
|
||||
entity->attrs.set(key, val.get<int>());
|
||||
}
|
||||
else {
|
||||
XLOGE() << key << ": [" << valType << "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 保存设备 entity 到 map
|
||||
if (entity->deviceId != -1)
|
||||
{
|
||||
mapDevices[entity->deviceId] = entity;
|
||||
}
|
||||
|
||||
// 启动通讯,该函数中会自动判断isOpen状态,选择是否进行通讯连接
|
||||
entity->startComm();
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<DeviceEntity>> Device::getDeviceByType(int type)
|
||||
{
|
||||
std::vector<std::shared_ptr<DeviceEntity>> vecDevice;
|
||||
for (auto iter = mapDevices.begin(); iter!=mapDevices.end(); ++iter)
|
||||
{
|
||||
auto device = iter->second;
|
||||
if (device && (type<=0 || device->type == type))
|
||||
{
|
||||
vecDevice.push_back(device);
|
||||
}
|
||||
}
|
||||
return vecDevice;
|
||||
}
|
||||
@@ -1,7 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <common/DataFields.h>
|
||||
|
||||
class CommEntity;
|
||||
|
||||
class DeviceEntity
|
||||
{
|
||||
public:
|
||||
int deviceId = -1;
|
||||
int type = -1;
|
||||
std::string name;
|
||||
std::string code;
|
||||
bool isOpen = false;
|
||||
std::string attrsJson = "";
|
||||
|
||||
|
||||
int err = 0;
|
||||
int online = 0;
|
||||
int status = 0;
|
||||
|
||||
|
||||
//std::map<std::string, std::string> mapAttrs;
|
||||
DataFields attrs;
|
||||
|
||||
// 通讯entity
|
||||
std::shared_ptr<CommEntity> commEntity;
|
||||
|
||||
//int getAttrInt(std::string key);
|
||||
//float getAttrFloat(std::string key);
|
||||
//double getAttrDouble(std::string key);
|
||||
//std::string getAttrStr(std::string key);
|
||||
|
||||
// 启动通讯
|
||||
int startComm();
|
||||
};
|
||||
|
||||
|
||||
class Device
|
||||
{
|
||||
public:
|
||||
static bool init();
|
||||
};
|
||||
static void add(DataFields& fields);
|
||||
|
||||
static std::vector<std::shared_ptr<DeviceEntity>> getDeviceByType(int type);
|
||||
|
||||
public:
|
||||
static std::map<int, std::shared_ptr<DeviceEntity>> mapDevices;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
|
||||
bool Operator::login(std::string account, std::string passwd, std::string& err)
|
||||
{
|
||||
bool ret = DAO::login(nullptr, account, passwd, err);
|
||||
|
||||
if (ret)
|
||||
auto ecode = DAO::login(nullptr, account, passwd, err);
|
||||
if (ecode == Errcode::OK)
|
||||
{
|
||||
XLOGD() << "用户[" + account + "]登录成功";
|
||||
}
|
||||
@@ -14,5 +13,5 @@ bool Operator::login(std::string account, std::string passwd, std::string& err)
|
||||
{
|
||||
XLOGD() << "用户[" + account + "]登录失败: " << err;
|
||||
}
|
||||
return ret;
|
||||
return (ecode == Errcode::OK);
|
||||
}
|
||||
15
src/app/errcode.h
Normal file
15
src/app/errcode.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
enum class Errcode
|
||||
{
|
||||
OK = 0,
|
||||
|
||||
ERR = 100,
|
||||
|
||||
ERR_DB_CONN = 101, // 数据库连接错误
|
||||
ERR_DB_SQL = 102, // 数据库查询SQL错误
|
||||
|
||||
ERR_LOGIN_USER_NOTEXIST = 103, // 登入错误,用户不存在
|
||||
ERR_LOGIN_PASSWD = 104, // 登入错误,密码不正确
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user