上传项目代码

This commit is contained in:
lixiaoyuan
2025-05-19 09:54:33 +08:00
commit 4a198a7271
589 changed files with 993786 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
#include "DbSqlite.h"
#include <iostream>
#include <string>
#include "common/Spdlogger.h"
DbSqlite::DbSqlite(const char* dbName)
{
if (SQLITE_OK != sqlite3_open(dbName, &sqlite_))
{
Spdlogger::error("open sqlite failed");
}
else
{
Spdlogger::info("open sqlite success");
}
}
DbSqlite::~DbSqlite()
{
this->close();
}
void DbSqlite::open(const char* dbname)
{}
void DbSqlite::close()
{
if (sqlite_ != nullptr)
{
sqlite3_close(sqlite_);
}
}
bool DbSqlite::exec(const char* sql)
{
char* errMsg;//操作失败的原因。
//std::string ssql="CREATE TABLE T_USER(username varchar(30) unique)";
if (SQLITE_OK != sqlite3_exec(sqlite_, sql, 0, 0, &errMsg))
{
Spdlogger::error("create table failed:{}", errMsg);
return false;
}
return true;
}
bool DbSqlite::prepare_step(const char* sql, CallbackSqliteRowData& cb)
{
sqlite3_stmt* stmt = nullptr;
if (SQLITE_OK != sqlite3_prepare_v2(sqlite_, sql, -1, &stmt, 0))
{
Spdlogger::error("sqlite3_prepare_v2 failed:");
return false;
}
Spdlogger::info("sqlite3 step sql=", sql);
while (SQLITE_ROW == sqlite3_step(stmt))
{
Spdlogger::info("sqlite3_step row data:");
if (cb) { cb(stmt); }
}
sqlite3_finalize(stmt);
return true;
}
int DbSqlite::get_int(sqlite3_stmt* stmt, int index)
{
return sqlite3_column_int(stmt, index);
}
double DbSqlite::get_double(sqlite3_stmt* stmt, int index)
{
return sqlite3_column_double(stmt, index);
}
std::string DbSqlite::get_text(sqlite3_stmt* stmt, int index)
{
return (char*)sqlite3_column_text(stmt, index);
}

32
src/database/0/DbSqlite.h Normal file
View File

@@ -0,0 +1,32 @@
#ifndef _DbSqlite_H_
#define _DbSqlite_H_
#include "sqlite3.h"
#include <string>
#include <functional>
using CallbackSqliteRowData = std::function<void(sqlite3_stmt*)>;
class DbSqlite
{
public:
DbSqlite(const char* dbname);
~DbSqlite();
void open(const char* dbname);
bool exec(const char* sql);
bool prepare_step(const char* sql, CallbackSqliteRowData& cb);
void close();
int get_int(sqlite3_stmt* stmt, int index);
double get_double(sqlite3_stmt* stmt, int index);
std::string get_text(sqlite3_stmt* stmt, int index);
private:
sqlite3* sqlite_ = nullptr;
};
#endif // !!! _DbSqlite_H_

218
src/database/DaoEntity.cpp Normal file
View File

@@ -0,0 +1,218 @@
#include "DaoEntity.h"
//#include "PvInstance.h"
//#include "spdlogger.h"
MysqlOptions DaoEntity::options_;
DaoEntity::DaoEntity(string tb_name)
{
//MysqlOptions opts;
//opts.host = "localhost";
//opts.user = "root";
//opts.password = "123456";
//opts.port = 3306;
//opts.dbname = "pvb";
db_ = make_shared<MysqlClient>(DaoEntity::options_);
if (!db_->isConnected())
{
//Global::data().status_msg = "数据库连接异常!";
//PvInstance::send_user_event(nullptr, EUserEvent::ALARM_DB, "数据库连接异常!");
}
tableName_ = tb_name;
}
DaoEntity::~DaoEntity()
{
db_ = nullptr;
}
MysqlOptions& DaoEntity::mysqlOptions()
{
return DaoEntity::options_;
}
std::shared_ptr<DaoEntity> DaoEntity::create(string tb_name)
{
std::shared_ptr<DaoEntity> dao = std::make_shared<DaoEntity>(tb_name);
return (dao->isConnected() ? dao : nullptr);
}
bool DaoEntity::execOnce(string sql)
{
auto db = make_shared<MysqlClient>(DaoEntity::options_);
return db->exec(sql);
}
bool DaoEntity::execOnce(string sql, vector<DataFields>& result)
{
auto db = make_shared<MysqlClient>(DaoEntity::options_);
return db->exec(sql, result);
}
void DaoEntity::setTableName(string tb_name)
{
tableName_ = tb_name;
}
bool DaoEntity::isConnected()
{
return db_->isConnected();
}
bool DaoEntity::exec(string sql)
{
return db_->exec(sql);
}
bool DaoEntity::exec(string sql, vector<DataFields>& result)
{
return db_->exec(sql, result);
}
bool DaoEntity::insertFields(DataFields& fields)
{
string sql = fields.get_insert_sql(tableName_);
return this->db_->exec(sql);
}
bool DaoEntity::insertFields(vector<DataFields>& vec_fields)
{
//"insert into TABLE () values ()";
string sql = "insert into " + tableName_;
bool first = true;
string keys;
string values;
for (auto& field : vec_fields)
{
keys = "";
values = "";
for (auto& item : field.fields())
{
const string& k = item.first;
const string& v = item.second;
if (first)
{
if (!keys.empty())
{
keys += ",";
}
keys += k;
}
if (!values.empty())
{
values += ",";
}
values += ("'" + v + "'");
}
if (first)
{
sql += (" (" + keys + ")");
sql += (" values (" + values + ")");
first = !first;
}
else
{
sql += (",(" + values + ")");
}
}
sql += ";";
return this->db_->exec(sql);
}
bool DaoEntity::duplicateUpdate(DataFields& fields, vector<string>& keys)
{
//insert into device_attr(device_id, attr_id, attr_val) values('26', 'model', '型号1') on duplicate key update attr_val='型号1';
string s_key;
string s_val;
for (auto& item : fields.fields())
{
if (!s_key.empty())
{
s_key += ","; s_val += ",";
}
s_key += (item.first);
s_val += ("'" + item.second + "'");
}
string s_data;
for (auto& k : keys)
{
if (!s_data.empty())
{
s_data += ",";
}
s_data += (k + "='" + fields.get_str(k) + "'");
}
string sql = "INSERT INTO " + tableName_ + "(" + s_key + ") VALUES (" + s_val + ") ON duplicate KEY UPDATE " + s_data;
return this->db_->exec(sql);
}
//void DaoEntity::queryFields(const string& condition, DaoPageinfo& pageinfo, vector<map<string, string>>& result)
//{
// this->query_by_page(condition, pageinfo, [&](map<string, string>& row) mutable {
// result.push_back(row);
// });
//}
bool DaoEntity::queryFields(string keys, const string& sql_c, vector<DataFields>& result)
{
ostringstream oss;
oss << "SELECT " + keys + " FROM " << tableName_ << (" " + sql_c) << "; ";
return this->db_->exec(oss.str(), result);
}
bool DaoEntity::queryFields(string keys, const string& sql_c, PageInfo& pageinfo, vector<DataFields>& result)
{
ostringstream oss;
oss << "SELECT count(1) total FROM `" << tableName_ << "` " << sql_c << ";";
vector<DataFields> res_total;
if (!this->db_->exec(oss.str().c_str(), res_total))
{
return false;
}
if (res_total.size() <= 0)
{
pageinfo.total = 0;
return true;
}
pageinfo.total = res_total[0].get_int("total");
if (pageinfo.total <= 0)
{
return true;
}
pageinfo.page_max = pageinfo.total / pageinfo.page_size + (pageinfo.total % pageinfo.page_size > 0 ? 1 : 0);
oss.str("");
if (pageinfo.page_id <= 0)
{
pageinfo.page_id = 1;
}
int start = (pageinfo.page_id - 1) * pageinfo.page_size;
oss << "SELECT " << keys << " FROM `" << tableName_ << "` " << sql_c << " LIMIT " << start << "," << pageinfo.page_size << ";";
return this->db_->exec(oss.str().c_str(), result);
}
bool DaoEntity::updateFields(DataFields& fields, const string& sql_c)
{
string sql = fields.get_update_sql(tableName_, sql_c);
if (sql_c.empty())
{
//Spdlogger::error("[DB] update condition is empty, not exec, sql={}", sql);
return false;
}
return this->db_->exec(sql.c_str());
}
bool DaoEntity::updateFields(DataFields& fields, vector<string> vec_keys, const string& sql_c)
{
string sql = fields.get_update_sql(tableName_, vec_keys, sql_c);
if (sql_c.empty())
{
//Spdlogger::error("[DB] update condition is empty, not exec, sql={}", sql);
return false;
}
return this->db_->exec(sql.c_str());
}

111
src/database/DaoEntity.h Normal file
View File

@@ -0,0 +1,111 @@
#ifndef _DaoBase_H_
#define _DaoBase_H_
#include "MysqlClient.h"
class DaoEntity
{
public:
DaoEntity(string tableName);
~DaoEntity();
static MysqlOptions& mysqlOptions();
static std::shared_ptr<DaoEntity> create(string tableName);
/**
* 执行sql语句
* @param: sql 要执行的完整 sql 语句
*/
static bool execOnce(string sql);
/**
* 执行sql语句返回结果数据集
* @param: sql 要执行的完整 sql 语句
* @param: result 返回的结果数据集
*/
static bool execOnce(string sql, vector<DataFields>& result);
/**
* 设置数据库表名称
* @param: tableName 数据表名
*/
void setTableName(string tableName);
/**
* 设置数据库表名称
* @return: bool true: 连接成功false未连接/连接失败
*/
bool isConnected();
/**
* 执行sql语句
*/
bool exec(string sql);
/**
* 执行sql语句并返回执行查询的结果集
*/
bool exec(string sql, vector<DataFields>& result);
/**
* 数据库插入一条数据, 需要先指定数据表名称
* @param: fields 写入的数据字段和值
*/
bool insertFields(DataFields& vecFields);
/**
* 数据库插入多条数据, 需要先指定数据表名称
* @param: vecFields 写入的数据字段和值的集合
*/
bool insertFields(vector<DataFields>& vecFields);
/**
* 数据库插入多条数据UNIQUE索引或PRIMARY KEY重复时执行更新数据, 需要先指定数据表名称
* @param: vecFields 写入的数据字段和值的集合
* @param: keys 数据重复时需要更新的字段
*/
bool duplicateUpdate(DataFields& vecFields, vector<string>& keys);
/**
* 数据库查询,需要先指定数据表名称
* @param: sql_c 查询条件,例:"where id='1'"
* @param: result 查询的数据结果集
*/
bool queryFields(string keys, const string& sql_c, vector<DataFields>& result);
/**
* 数据库查询,需要先指定数据表名称
* @param: sql_c 查询条件,例:"where id='1'"
* @param: pageinfo 分页信息
* @param: result 查询的数据结果集
*/
bool queryFields(string keys, const string& sql_c, PageInfo& pageinfo, vector<DataFields>& result);
/**
* 数据库更新,需要先指定数据表名称
* @param: fields 要更新的数据字段和值
* @param: sql_c 更新条件
*/
bool updateFields(DataFields& fields, const string& sql_c);
/**
* 数据库更新,需要先指定数据表名称
* @param: fields 要更新的数据值
* @param: vecKeys 要更新的字段名称
* @param: cond 更新条件
*/
bool updateFields(DataFields& fields, vector<string> vecKeys, const string& cond);
protected:
static MysqlOptions options_;
// mysql 数据库操作对象
std::shared_ptr<MysqlClient> db_ = nullptr;
// 数据库表名称
string tableName_;
};
#endif // !!! _DaoBase_H_

View File

@@ -0,0 +1,122 @@
#include "MysqlClient.h"
#include "common/Utils.h"
//#include "Spdlogger.h"
#include "Logger.h"
MysqlClient::MysqlClient(MysqlOptions opts) : options_(opts)
{
conn();
}
MysqlClient::~MysqlClient()
{
this->close();
}
int MysqlClient::conn()
{
if (mysql_)
{
return 0;
}
mysql_ = mysql_init(nullptr);
MYSQL* ret = mysql_real_connect(mysql_, options_.host.c_str(), options_.user.c_str(), options_.password.c_str(), options_.dbname.c_str(), options_.port, NULL, 0);
if (ret == NULL)
{
//Spdlogger::info("[mysql] connect failed: {}", mysql_error(mysql_));
mysql_ = nullptr;
}
else
{
mysql_query(mysql_, "set names 'utf8';");
}
return 0;
}
bool MysqlClient::isConnected()
{
return (mysql_ != nullptr);
}
void MysqlClient::close()
{
if (mysql_)
{
mysql_close(mysql_);
mysql_ = nullptr;
}
}
bool MysqlClient::exec(std::string sql)
{
XLOGD() << "Mysql exec sql=" << sql;
if (!mysql_)
{
XLOGE() << "Mysql exec error, database is not connected.";
return false;
}
int ret = mysql_query(mysql_, sql.c_str());
if (0 != ret)
{
XLOGE() << "Mysql exec error: " << mysql_error(mysql_) << ", sql=" << sql;
return false;
}
return true;
}
bool MysqlClient::exec(std::string sql, vector<DataFields>& result)
{
result.clear();
if (!mysql_)
{
return false;
}
int ret = mysql_query(mysql_, sql.c_str());
if (0 != ret)
{
//Spdlogger::error("[mysql] mysql_query failed!! error ret={:d}, sql={}", ret, sql);
XLOGE() << "mysql error: " << sql;
return false;
}
else
{
//Spdlogger::info("[mysql] query success. sql={}", sql);
}
MYSQL_RES* res = mysql_store_result(mysql_);
if (!res)
{
return false;
}
vector<string> field_names;
while (true)
{
MYSQL_FIELD* field = mysql_fetch_field(res);
if (!field)
{
break;
}
field_names.push_back(field->name);
}
while (true)
{
MYSQL_ROW row = mysql_fetch_row(res);
if (!row)
{
break;
}
DataFields row_data;
for (size_t i = 0; i < field_names.size(); ++i)
{
string field_text = (row[i] == NULL) ? "" : row[i];
row_data.set(field_names[i], field_text);
}
result.push_back(row_data);
}
// 释放结果集
mysql_free_result(res);
return true;
}

View File

@@ -0,0 +1,68 @@
#ifndef _DbMysql_H_
#define _DbMysql_H_
#pragma warning(disable:4100)
#include <sstream>
#include <memory>
#include <iostream>
#include <functional>
#include <string>
#include <map>
#include <vector>
#include "mysql.h"
#include "DataFields.h"
using namespace std;
struct MysqlOptions
{
std::string host;
std::string user;
std::string password;
std::string dbname;
int port;
};
class MysqlClient
{
public:
MysqlClient(MysqlOptions options);
~MysqlClient();
/**
* @brief: 连接MYSQL数据库
* return: [int]
*/
int conn();
/**
* @brief 是否成功连接数据库
* @return true:连接成功false:未连接或连接失败
*/
bool isConnected();
/**
* @brief: 关闭数据库连接
*/
void close();
/**
* @brief: 执行sql语句
*/
bool exec(std::string sql);
/**
* @brief: 执行sql语句, 获取查询结果集
*/
bool exec(std::string, vector<DataFields>& result);
private:
// mysql数据库连接对象
MYSQL* mysql_ = nullptr;
// 数据库连接信息
MysqlOptions options_;
};
#endif // !!! _DbMysql_H_

88
src/database/SQL.h Normal file
View File

@@ -0,0 +1,88 @@
#pragma once
#include <string>
class SQL
{
public:
enum class TYPE
{
insert = 1,
select,
update,
del,
};
SQL(TYPE t = TYPE::select) : type(t)
{
}
std::string str()
{
if (type == TYPE::select)
{
// SELECT * from t_tabname WHERE id='1';
if (sql_k.empty()) {}
std::string s = "SELECT " + (sql_k.empty() ? "*" : sql_k) + " FROM `" + tabname + "`";
if (!sql_c.empty()) { s += (" WHERE" + sql_c); }
return s + ";";
}
else if (type == TYPE::update)
{
// UPDATE t_tabname SET a='1', b='2' WHERE id='1';
std::string s = "UPDATE `" + tabname + "` SET " + sql_k + " WHERE" + sql_c;
return s + ";";
}
else if (type == TYPE::insert)
{
// INSERT INTO t_tabname (a,b,c) VALUES('1','2','3');
std::string s = "INSERT INTO `" + tabname + "` (" + sql_k + ") VALUES(" + sql_v + ");";
return s;
}
else if (type == TYPE::del)
{
return "";
}
return "";
}
SQL& table(std::string t)
{
tabname = t;
return *this;
}
SQL& select(std::string k)
{
if (!sql_k.empty()) { sql_k += ","; }
sql_k += k;
return *this;
}
SQL& where(std::string expr)
{
sql_c += (" " + expr);
return *this;
}
SQL& update(std::string k, std::string v)
{
if (!sql_k.empty()) { sql_k += ","; }
sql_k += ("`" + k + "`='" + v + "'");
return *this;
}
SQL& insert(std::string k, std::string v)
{
if (!sql_k.empty()) { sql_k += ","; }
sql_k += ("`" + k + "`");
if (!sql_v.empty()) { sql_v += ","; }
sql_v += ("'" + v + "'");
return *this;
}
private:
TYPE type = TYPE::select;
std::string tabname;
std::string sql_k;
std::string sql_v;
std::string sql_c;
};

View File

@@ -0,0 +1,120 @@
#include "DaoAdmin.h"
#include "Crypto.h"
#include "database/DaoEntity.h"
#include "common/Snowflake.h"
bool DaoAdmin::insert_operator(DataFields& fields)
{
// 数据库 id 自增
fields.remove(DMOperator::FID_ID);
DaoEntity dao(DMOperator::TABLENAME);
return dao.insert_fields(fields);
}
bool DaoAdmin::update_operator_by_id(DataFields& fields)
{
string id = fields.get_str(DMOperator::FID_ID);
fields.remove(DMOperator::FID_ID);
fields.remove(DMOperator::FID_CREATETIME);
fields.remove(DMOperator::FID_UPDATETIME);
fields.set(DMOperator::FID_PASSWD, Crypto::md5("123456"));
DaoEntity dao(DMOperator::TABLENAME);
return dao.update_fields(fields, "WHERE id='" + id + "'");
}
bool DaoAdmin::query_operator_page(PageInfo& pageinfo, vector<DataFields>& result)
{
DaoEntity dao(DMOperator::TABLENAME);
return dao.query_fields("*", "", pageinfo, result);
}
bool DaoAdmin::query_operator_by_name(string name, vector<DataFields>& result)
{
string sql_c = "where username = '" + name + "';";
DaoEntity dao(DMOperator::TABLENAME);
return dao.query_fields("*", sql_c, result);
}
static void LogDaoResult(vector<DataFields>& vec_fields)
{
for (int i = 0; i < vec_fields.size(); i++)
{
string s = "{";
vec_fields[i].foreach_item([&](string key, string val)
{
s += (key + ":" + val + ", ");
});
s = s.substr(0, s.size() - 2);
s += "}";
}
}
bool DaoAdmin::query_role(vector<DataFields>& result)
{
DaoEntity dao(DMRole::TABLENAME);
dao.query_fields("*", "", result);
LogDaoResult(result);
return true;
}
bool DaoAdmin::update_role_by_id(DataFields& fields)
{
string id = fields.get_str(DMRole::FID_ID);
fields.remove(DMRole::FID_ID);
string sql_c = "where " + DMRole::FID_ID + "='" + id + "'";
DaoEntity dao(DMRole::TABLENAME);
return dao.update_fields(fields, sql_c);
}
int DaoAdmin::insert_permission(DataFields& fields)
{
DaoEntity dao(DMPermission::TABLENAME);
return dao.insert_fields(fields);
}
bool DaoAdmin::query_permission(PageInfo& pageinfo, vector<DataFields>& result, string sql_c)
{
DaoEntity dao(DMPermission::TABLENAME);
return dao.query_fields("*", sql_c, pageinfo, result);
}
bool DaoAdmin::update_permission(DataFields& fields, const string& sql_c)
{
fields.remove(DMPermission::FID_ID);
DaoEntity dao(DMPermission::TABLENAME);
return dao.update_fields(fields, sql_c);
}
bool DaoAdmin::query_admin_permission(string account, vector<DataFields>& result)
{
string sql = "select role.role_name, role_permission.*, permission.func from operator "
"left join role on operator.role_name = role.role_name "
"left join role_permission on role_permission.role_id = role.id "
"left join permission on permission.id = role_permission.permission_id "
"where operator.username = '" + account + "' order by permission_id; ";
return DaoEntity::exec_once(sql, result);
}
int DaoAdmin::insert_policy(DataFields& fields)
{
DaoEntity dao(DMPolicy::TABLENAME);
return dao.insert_fields(fields);
}
bool DaoAdmin::query_policy(PageInfo& pageinfo, vector<DataFields>& result, string sql_c)
{
DaoEntity dao(DMPolicy::TABLENAME);
return dao.query_fields("*", sql_c, pageinfo, result);
}
bool DaoAdmin::update_policy(DataFields& fields, const string& sql_c)
{
fields.remove(DMPolicy::FID_ID);
fields.remove(DMPolicy::FID_UPDATE_TIME);
DaoEntity dao(DMPolicy::TABLENAME);
return dao.update_fields(fields, sql_c);
}

118
src/database/dao/DaoAdmin.h Normal file
View File

@@ -0,0 +1,118 @@
#pragma once
#include "DataFields.h"
struct PageInfo;
namespace DMOperator
{
const string TABLENAME = "operator";
const string FID_ID = "id";
const string FID_USERNAME = "username";
const string FID_PASSWD = "passwd";
const string FID_REALNAME = "real_name";
const string FID_PHONE = "phone";
const string FID_ROLE = "role_name";
const string FID_CREATETIME = "create_time";
const string FID_UPDATETIME = "update_time";
}
namespace DMRole
{
const string TABLENAME = "role";
const string FID_ID = "id";
const string FID_ROLE_NAME = "role_name";
const string FID_ROLE_NO = "role_no";
const string FID_TYPE = "type";
const string FID_DESCRIBE = "describe";
const string FID_IS_OPEN = "is_open";
}
namespace DMPermission
{
const string TABLENAME = "permission";
const string FID_ID = "id";
const string FID_FUNC = "func";
const string FID_URL = "url";
const string FID_REMARK = "remark";
}
namespace DMRolePermission
{
const string TABLENAME = "role_permission";
const string FID_ID = "id";
const string FID_ROLE_ID = "role_id";
const string FID_PERMISSION_ID = "permission_id";
}
namespace DMPolicy
{
const string TABLENAME = "policy";
const string FID_ID = "id";
const string FID_TYPE = "type";
const string FID_CODE = "code";
const string FID_NAME = "name";
const string FID_VALUE = "value";
const string FID_REMARK = "remark";
const string FID_IS_OPEN = "is_open";
const string FID_UPDATE_TIME = "update_time";
}
class DaoAdmin
{
public:
// ************************************************************************************************
// 操作员账号管理
/**
* 更新操作员信息
* @param: fields 更新的字段信息
* @param: sql_c 更新条件, 例:"where id='1'"
*/
static bool insert_operator(DataFields& fields);
/**
* 更新操作员信息
* @param: fields 更新的字段信息
*/
static bool update_operator_by_id(DataFields& fields);
/**
* 分页查询操作员信息
* @param: pageinfo 分页信息
* @paramresult 查询结果数据集
*/
static bool query_operator_page(PageInfo& pageinfo, vector<DataFields>& result);
static bool query_operator_by_name(string name, vector<DataFields>& result);
// ************************************************************************************************
// 权限管理
//
static int insert_permission(DataFields& fields);
static bool query_permission(PageInfo& pageinfo, vector<DataFields>& result, string sql_c);
static bool update_permission(DataFields& fields, const string& sql_c);
// ************************************************************************************************
// 角色管理
static bool query_role(vector<DataFields>& result);
static bool update_role_by_id(DataFields& fields);
static bool query_admin_permission(string account, vector<DataFields>& result);
// ************************************************************************************************
// 策略管理
static int insert_policy(DataFields& fields);
static bool query_policy(PageInfo& pageinfo, vector<DataFields>& result, string sql_c);
static bool update_policy(DataFields& fields, const string& sql_c);
};

View File

@@ -0,0 +1,81 @@
#include "DaoBattery.h"
#include "database/DaoEntity.h"
void DaoBattery::insert_battery(DataFields& fields)
{
// ID为自增
fields.remove(DMBattery::ID);
fields.check(DMBattery::BATTERY_NUM, "", "0");
DaoEntity dao(DMBattery::TABLENAME);
dao.insert_fields(fields);
}
void DaoBattery::query_battery(PageInfo& pageinfo, vector<DataFields>& result, string sql_c)
{
DaoEntity dao(DMBattery::TABLENAME);
dao.query_fields("*", sql_c, pageinfo, result);
}
void DaoBattery::query_battery(vector<DataFields>& result)
{
PageInfo pageinfo;
pageinfo.page_id = 0;
pageinfo.page_size = 100;
DaoEntity dao(DMBattery::TABLENAME);
dao.query_fields("*", "", pageinfo, result);
}
void DaoBattery::query_battery_by_code(string code, vector<DataFields>& result)
{
DaoEntity dao(DMBattery::TABLENAME);
string sql_c = "where code='" + code + "'";
dao.query_fields("*", sql_c, result);
}
bool DaoBattery::query_battery_by_pos(string storage_id, vector<DataFields>& result)
{
string sql = "select * from " + DMBattery::TABLENAME + " where " + DMBattery::ID + "='" + storage_id + "'";
return DaoEntity::exec_once(sql, result);
}
int DaoBattery::update_battery(DataFields& fields, string condition)
{
DaoEntity dao(DMBattery::TABLENAME);
fields.check("business_time", "", "NULL");
fields.check("cool_type", "", "NULL");
fields.check("status", "", "NULL");
return dao.update_fields(fields, condition);
}
bool DaoBattery::insert_battery_data(DataFields& fields)
{
DaoEntity dao(DMBatteryData::TABLENAME);
return dao.insert_fields(fields);
}
bool DaoBattery::update_battery_bms(std::string batt_code, DataFields& fields)
{
string sql_c = " WHERE " + DMBatteryData::FID_BATTERY_CODE + "='" + batt_code + "'";
vector<DataFields> result;
DaoEntity dao(DMBatteryData::TABLENAME);
string sql = "select count(1) count from " + DMBatteryData::TABLENAME + sql_c;
bool ret = dao.exec(sql, result);
if (!ret)
{
return false;
}
if (result.size() > 0)
{
if (result[0].get_int("count") > 0)
{
// UPDATE
return dao.update_fields(fields, sql_c);
}
}
// INSERT
fields.set(DMBatteryData::FID_BATTERY_CODE, batt_code);
return dao.insert_fields(fields);
}

View File

@@ -0,0 +1,57 @@
#pragma once
#include "DataFields.h"
namespace DMBattery
{
const string TABLENAME = "battery";
const string ID = "id";
const string CODE = "code";
const string MODEL = "model";
const string TYPE = "type";
const string LOCK_TYPE = "lock_type";
const string FACTOR = "factory";
const string CAPACITY = "rated_capacity"; // 额定容量
const string RATED_VOLTAGE = "rated_voltage"; // 额定电压
const string TOTALENERGY = "rated_total_energy"; // 额定总能量
const string VOLTAGE_MAX = "voltage_max"; // 最高充电电压
const string BATTERY_NUM = "battery_num"; // 单体电池个数
}
namespace DMBatteryData
{
const string TABLENAME = "battery_status";
const string FID_ID = "id";
const string FID_BATTERY_CODE = "battery_code";
const string FID_POSID = "storehouse_id";
const string FID_VOLTAGE = "voltage";
const string FID_CURRENT = "current";
const string FID_POWER = "power";
const string FID_SOC = "soc";
const string FID_SOH = "soh";
const string FID_MAX_VOLTAGE = "max_voltage";
const string FID_MAX_VOLTAGE_ID = "max_voltage_id";
const string FID_MIN_VOLTAGE = "min_voltage";
const string FID_MIN_VOLTAGE_ID = "min_voltage_id";
const string FID_MAX_TEMP = "max_temp";
const string FID_MAX_TEMP_ID = "max_temp_id";
const string FID_MIN_TEMP = "min_temp";
const string FID_MIN_TEMP_ID = "min_temp_id";
const string FID_CREATE_TIME = "cteate_time";
}
class DaoBattery
{
public:
static void insert_battery(DataFields& fields);
static void query_battery(PageInfo& pageinfo, vector<DataFields>& result, string condition = "");
static void query_battery(vector<DataFields>& result);
static void query_battery_by_code(string code, vector<DataFields>& result);
static bool query_battery_by_pos(string storage_id, vector<DataFields>& result);
static int update_battery(DataFields& fields, string condition);
static bool insert_battery_data(DataFields& fields);
static bool update_battery_bms(std::string batt_code, DataFields& fields);
};

View File

@@ -0,0 +1,49 @@
#include "DaoCar.h"
#include "database/DaoEntity.h"
#include "database/dao/DaoDevice.h"
bool DaoCar::query_car_page(PageInfo& pageinfo, vector<DataFields>& result)
{
// 查询数据库
DaoEntity dao(DMCar::TABLENAME);
return dao.query_fields("*", "", pageinfo, result);
}
bool DaoCar::query_car_by_userid(string userid, vector<DataFields>& result)
{
string sql = "select * from car where user_id='" + userid + "';";
return DaoEntity::exec_once(sql, result);
}
bool DaoCar::query_car_by_carnum(string carnum, vector<DataFields>& result)
{
string sql = "select * from car where car_no='" + carnum + "';";
return DaoEntity::exec_once(sql, result);
}
bool DaoCar::insert_car(DataFields& fields)
{
fields.check(DMCar::FID_RANGE, "", "0");
fields.check(DMCar::FID_PRODUCT_DATE, "", "NULL");
fields.check(DMCar::FID_BUY_DATE, "", "NULL");
fields.remove(DMCar::FID_CREATE_TIME);
DaoEntity dao(DMCar::TABLENAME);
return dao.insert_fields(fields);
}
bool DaoCar::update_car(DataFields& fields)
{
fields.check(DMCar::FID_RANGE, "", "0");
fields.check(DMCar::FID_PRODUCT_DATE, "", "NULL");
fields.check(DMCar::FID_BUY_DATE, "", "NULL");
fields.remove(DMCar::FID_CREATE_TIME);
DaoEntity dao(DMCar::TABLENAME);
string id = fields.get_str(DMCar::FID_ID);
fields.remove(DMDevice::ID);
return dao.update_fields(fields, "where id='" + id + "'");
}

41
src/database/dao/DaoCar.h Normal file
View File

@@ -0,0 +1,41 @@
#pragma once
#include "DataFields.h"
namespace DMCar
{
const string TABLENAME = "car";
const string FID_ID = "id";
const string FID_USER_ID = "user_id";
const string FID_FRAME_NUM = "frame_no";
const string FID_CAR_NUM = "car_no";
const string FID_BRAND = "brand";
const string FID_FACTORY = "factory";
const string FID_MODEL = "model";
const string FID_RANGE = "range";
const string FID_PRODUCT_DATE = "product_date";
const string FID_BUY_DATE = "buy_time";
const string FID_BATTERY_MODEL = "battery_model";
const string FID_CREATE_TIME = "create_time";
const string FID_BATT_CODE = "batt_code";
}
class DaoCar
{
public:
// ************************************************************************************************
// 车辆信息管理
static bool insert_car(DataFields& fields);
// 更新车辆信息更新条件id
static bool update_car(DataFields& fields);
/**
* 分页查询设备信息
* @param: pageinfo 分页信息
* @param: result 查询的结果数据集
*/
static bool query_car_page(PageInfo& pageinfo, vector<DataFields>& result);
static bool query_car_by_userid(string userid, vector<DataFields>& result);
static bool query_car_by_carnum(string carnum, vector<DataFields>& result);
};

View File

@@ -0,0 +1,48 @@
#include "DaoCharge.h"
#include "app/Global.h"
#include "common/spdlogger.h"
#include "common/TimeUtils.h"
#include "common/Snowflake.h"
#include "database/DaoEntity.h"
#include "database/dao/DaoDevice.h"
#include "Device.h"
bool DaoCharge::create_charge_record(std::string biz_id, int device_id)
{
DataFields fields;
fields.set(DMChargeRecord::ID, biz_id);
fields.set(DMChargeRecord::DEVICE_ID, device_id);
DaoEntity dao(DMChargeRecord::TABLENAME);
return dao.insert_fields(fields);
}
bool DaoCharge::update_charge_record(std::string biz_id, int device_id, DataFields fields)
{
DaoEntity dao(DMChargeRecord::TABLENAME);
std::vector<DataFields> result;
dao.exec("select * from " + DMChargeRecord::TABLENAME + " WHERE id='" + biz_id + "';", result);
if (result.size() == 0)
{
fields.set(DMChargeRecord::ID, biz_id);
fields.set(DMChargeRecord::DEVICE_ID, device_id);
dao.insert_fields(fields);
}
fields.remove(DMChargeRecord::ID);
fields.remove(DMChargeRecord::DEVICE_ID);
return dao.update_fields(fields, "where " + DMChargeRecord::ID + "='" + biz_id + "'");
}
void DaoCharge::query_charger(vector<DataFields>& result)
{
DaoEntity dao(DMDevice::TABLENAME);
string sql = " where device.type='智能充电设备';";
dao.query_fields("*", sql, result);
}
void DaoCharge::query_charger_attr(vector<DataFields>& result)
{
DaoEntity dao(DMDevice::TABLENAME);
string sql = " left join device_attr on device.id =device_attr.device_id where device.type='智能充电设备';";
dao.query_fields("*", sql, result);
}

View File

@@ -0,0 +1,86 @@
#ifndef _DaoCharge_H_
#define _DaoCharge_H_
#include "DataFields.h"
namespace DMChargerData
{
const string TABLENAME = "charge_status";
const string ID = "id";
const string DEVICE_ID = "device_id";
const string STATUS = "status";
const string VOLTAGE = "voltage";
const string CURRENT = "current";
const string POWER = "power";
const string PEAK = "peak";
const string VALLEY = "valley";
const string SHARP = "sharp";
const string FLAT = "flat";
const string SOC = "soc";
const string CREATE_TIME = "create_time";
}
namespace DMChargeRecord
{
const string TABLENAME = "charge_record";
const string ID = "id";
const string DEVICE_ID = "device_id"; // 设备ID
const string BATTERY_CODE = "battery_code";
const string START_TIME = "start_time";
const string END_TIME = "end_time";
const string DURATION = "duration";
const string ELECTRICITY = "electricity"; // 本次充电电量
const string TOP_ELECT = "top_elect"; // 尖阶段电量
const string TOP_AMOUNT = "top_amount"; // 尖阶段电费
const string PEAK_ELECT = "peak_elect"; // 峰阶段电量
const string PEAK_AMOUNT = "peak_amount"; // 峰阶段电费
const string FLAT_ELECT = "flat_elect"; // 平阶段电量
const string FLAT_AMOUNT = "flat_amount"; // 平阶段电费
const string VALLEY_ELECT = "valley_elect"; // 谷阶段电量
const string VALLEY_AMOUNT = "valley_amount"; // 谷阶段电费
const string PAY_AMOUNT = "pay_amount"; // 本次充电金额
const string METER_VALUE_START = "meter_value_start"; // 电表总起值
const string METER_VALUE_END = "meter_value_end"; // 电表总止值
const string SOC_START = "soc_start"; // 充电前soc
const string SOC_END = "soc_end"; // 充电后soc
const string STATUS = "status"; // 状态
const string CHARGE_STOP_CAUSE = "charge_stop_cause"; // 停止原因
}
namespace DMChargeDataRecord
{
const string TABLENAME = "charge_data_record";
const string DEVICE_ID = "device_id";
const string DEVICE_CODE = "device_code";
const string COLLECT_TIME = "collect_time";
const string VOLTAGE = "voltage";
const string CURRENT = "current";
const string POWER = "power";
}
class DaoCharge
{
public:
/**
* 创建充电业务订单记录
* @param: [std::string biz_id] 充电业务订单ID
* @param: [std::string device_id] 充电业务的充电机设备ID
*/
static bool create_charge_record(std::string biz_id, int device_id);
/**
* 更新充电业务订单记录
* @param: [std::string biz_id] 充电业务订单ID
* @param: [DataFields fields] 需要更新的字段
*/
static bool update_charge_record(std::string biz_id, int device_id, DataFields fields);
static void query_charger(vector<DataFields>& result);
static void query_charger_attr(vector<DataFields>& result);
};
#endif // !_DaoCharge_H_

View File

@@ -0,0 +1,61 @@
#include "DaoDevice.h"
#include "database/DaoEntity.h"
void DaoDevice::insert_device(DataFields& fields)
{
fields.remove("id");
fields.check("open_time", "", "NULL");
fields.check("product_time", "", "NULL");
DaoEntity dao(DMDevice::TABLENAME);
dao.insert_fields(fields);
}
void DaoDevice::query_device_page(PageInfo& pageinfo, vector<DataFields>& result)
{
DaoEntity dao(DMDevice::TABLENAME);
dao.query_fields("*", "", pageinfo, result);
}
void DaoDevice::query_device(string sql_c, vector<DataFields>& result)
{
DaoEntity dao(DMDevice::TABLENAME);
dao.query_fields("*", sql_c, result);
}
void DaoDevice::query_device_attr(string sql_c, vector<DataFields>& result)
{
DaoEntity dao(DMDeviceAttr::TABLENAME);
string c = " left join device on device_attr.device_id=device.id " + sql_c + ";";
dao.query_fields("*", c, result);
}
int DaoDevice::update_device(DataFields& fields)
{
string id = fields.get_str(DMDevice::ID);
string sql_c = "WHERE id='" + id + "'";
fields.remove(DMDevice::ID);
fields.check(DMDevice::PRODUCT_DATE, "", "NULL");
fields.check(DMDevice::OPEN_TIME, "", "NULL");
DaoEntity dao(DMDevice::TABLENAME);
return dao.update_fields(fields, sql_c);
}
void DaoDevice::update_device_attr(vector<DataFields> vec_d)
{
DaoEntity dao(DMDeviceAttr::TABLENAME);
vector<string> v_keys = {DMDeviceAttr::ATTR_VAL};
for (auto& fields : vec_d)
{
dao.duplicate_update(fields, v_keys);
}
}
void DaoDevice::query_attr(int device_id, vector<DataFields>& result)
{
DaoEntity dao(DMDeviceAttr::TABLENAME);
string sql = " where device_id='" + to_string(device_id) + "'";
dao.query_fields("*", sql, result);
}

View File

@@ -0,0 +1,101 @@
#ifndef _DaoDevice_H_
#define _DaoDevice_H_
#include "DataFields.h"
namespace DMDevice
{
const string TABLENAME = "device";
const string ID = "id";
const string NAME = "name";
const string CODE = "code";
const string MODEL = "model";
const string TYPE = "type";
const string FACTORY = "factory";
const string TEL = "factory_tel";
const string PRODUCT_DATE = "product_time";
const string IS_OPEN = "is_open";
const string OPEN_TIME = "open_time";
const string COMM_TYPE = "comm_type";
const string COMM_PROTOCOL = "comm_protocol";
const string COMM_IP = "comm_ip";
const string COMM_PORT = "comm_port";
const string STATUS = "status";
const string CREATE_TIME = "create_time";
const string UPDATE_TIME = "update_time";
}
namespace DMDeviceAttr
{
const string TABLENAME = "device_attr";
const string DEVICE_ID = "device_id";
const string ATTR_ID = "attr_id";
const string ATTR_VAL = "attr_val";
// 属性ID的关键字
// 充电机属性
const string K_STORAGE_ID = "storage_id";
const string K_MODEL = "model";
const string K_MANUFACTOR = "manufactor";
const string K_RATED_POWER = "rated_power";
const string K_VOLTAGE_MIN = "voltage_min";
const string K_VOLTAGE_MAX = "voltage_max";
const string K_CURRENT_MAX = "current_max";
// 存储架属性:仓位电池型号和存储的电池编号
const string K_BATT_MODEL = "battery_model";
const string K_BATT_CODE = "battery_code";
// 电表属性:
const string K_LINK_DEVICE = "link_device";
}
namespace DMDeviceDataRecord
{
const string TABLENAME = "device_data_record";
const string DEVICE_ID = "device_id"; // 设备ID
const string COLLECT_TIME = "collect_time"; // 采集时间
const string VOLTAGE = "voltage"; // 电压
const string CURRENT = "current"; // 电流
const string POWER = "power"; // 功率
const string POWER_Q = "power_q"; // 无功功率
const string POWER_S = "power_s"; // 视在功率
const string FACTOR = "factor"; // 功率因数
}
class DaoDevice
{
public:
/**
* 新增设备信息, DataFields 的 key 见【namespace DaoDevice】中的定义
*/
static void insert_device(DataFields& fields);
/**
* 查询设备信息结果集字段见【namespace DaoDevice】中的定义
* @param: sql_c 查询条件: 例:"where id='1'"
* @param: result 查询的结果数据集
*/
static void query_device(string sql_c, vector<DataFields>& result);
static void query_device_attr(string sql_c, vector<DataFields>& result);
/**
* 分页查询设备信息
* @param: pageinfo 分页信息
* @param: result 查询的结果数据集
*/
static void query_device_page(PageInfo& pageinfo, vector<DataFields>& result);
/**
* 更新设备信息
* @param: fields 更新的字段信息,其中 DaoDevice::FID_ID 作为更新条件
*/
static int update_device(DataFields& fields);
// ************************************************************************************************
// 设备属性管理
static void update_device_attr(vector<DataFields> vec_d);
static void query_attr(int device_id, vector<DataFields>& result);
private:
};
#endif // !!!_DaoDevice_H_

View File

@@ -0,0 +1,84 @@
#include "DaoStat.h"
#include "database/DaoEntity.h"
#include "database/dao/DaoCharge.h"
#include "database/dao/DaoDevice.h"
#include "TimeUtils.h"
#include "database/SQL.h"
bool DaoStat::insert_charge_curve(DataFields& fields)
{
DaoEntity dao(DMChargeDataRecord::TABLENAME);
return dao.insert_fields(fields);
}
bool DaoStat::query_charge_curve_by_time(string start_time, string end_time, std::vector<DataFields>& result)
{
string sql = "select * from " + DMChargeDataRecord::TABLENAME + " where " + DMChargeDataRecord::COLLECT_TIME + ">='" + start_time
+ "' and " + DMChargeDataRecord::COLLECT_TIME + "<='" + end_time + "';";
return DaoEntity::exec_once(sql, result);
}
bool DaoStat::query_station_power_by_time(string start_time, string end_time, std::vector<DataFields>& result)
{
string sql = "select * from " + DMDeviceDataRecord::TABLENAME + " where " + DMDeviceDataRecord::COLLECT_TIME + ">='" + start_time
+ "' and " + DMDeviceDataRecord::COLLECT_TIME + "<='" + end_time + "';";
return DaoEntity::exec_once(sql, result);
}
#include "Device.h"
void DaoStat::insert_charger_data(int t_interval)
{
// 存储时间间隔60
// 记录上一次存储的时间点,用于计算防止重复存储
static uint64_t t_last = 0;
// 存储时间间隔: 从0点开始计算每间隔t_interval存储一次数据
uint64_t t_start = TimeUtils::datetime2ts(TimeUtils::now_date() + " 00:00:00");
uint64_t t_now = TimeUtils::now();
uint64_t a = (t_now - t_start) / t_interval;
uint64_t b = (t_now - t_start) % t_interval;
uint64_t t = t_start + a * t_interval;
if (t != t_last)
{
t_last = t;
std::string t_str = TimeUtils::ts2datetime(t);
DaoEntity dao(DMChargeDataRecord::TABLENAME);
for (int i = 1; i <= 6; i++)
{
std::string device_code = std::to_string(i);
auto charger = Device::get_charger(device_code);
if (charger)
{
float v = charger->bms.voltage + charger->bms.current + charger->bms.power;
if (v != 0.0f)
{
DataFields d;
d.set(DMChargeDataRecord::DEVICE_ID, charger->device_id);
d.set(DMChargeDataRecord::DEVICE_CODE, device_code);
d.set(DMChargeDataRecord::COLLECT_TIME, t_str);
d.set(DMChargeDataRecord::VOLTAGE, charger->bms.voltage);
d.set(DMChargeDataRecord::CURRENT, charger->bms.current);
d.set(DMChargeDataRecord::POWER, charger->bms.power);
dao.insert_fields({d});
}
}
}
}
}
bool DaoStat::query_charge_data(std::string dt, vector<DataFields>& result)
{
// 存储查询结果集
vector<DataFields> vec_result;
// 查询设备数据记录表
std::string sql_c = DMDeviceDataRecord::COLLECT_TIME + ">='" + dt + " 00:00:00"
+ "' AND " + DMDeviceDataRecord::COLLECT_TIME + "<='" + dt + " 23:59:59" + "'";
std::string sql = SQL(SQL::TYPE::select).table(DMDeviceDataRecord::TABLENAME).select("*").where(sql_c).str();
// 执行数据库查询
return DaoEntity::exec_once(sql, vec_result);
}

View File

@@ -0,0 +1,69 @@
#pragma once
#include "DataFields.h"
namespace DMStatSwap
{
const string TABLENAME = "stat_swap";
const string DT = "dt"; // 统计的日期(按天统计)
const string T_TOTAL = "t_total"; // 总换电时长
const string T_AVG = "t_avg"; // 平均换电时长
const string T_MIN = "t_min"; // 最快换电时长
const string T_MAX = "t_max"; // 最慢换电时长
const string ELECTRIC = "electric"; // 总电量
const string FEE_SERVICE = "fee_service"; // 服务费
const string FEE_ELECTRIC = "fee_electric"; // 电费
const string NUM = "num"; // 换电次数
const string NUM_SUCCESS = "num_success"; // 换电成功次数
const string NUM_FAILED = "num_failed"; // 换电失败次数
const string NUM_DF = "num_brand_df"; // 品牌车辆换电次数(东风)
const string NUM_WL = "num_brand_wl"; // 品牌车辆换电次数(蔚来)
const string NUM_BQ = "num_brand_bq"; // 品牌车辆换电次数(北汽)
}
namespace DMStatCharge
{
const string TABLENAME = "stat_charge";
const string DT = "dt";
const string T_TOTAL = "t_total";
const string T_AVG = "t_avg";
const string T_MIN = "t_min";
const string T_MAX = "t_max";
const string T_ONLINE = "t_online";
const string ELECTRIC = "electric";
const string ELECT_AVG = "elect_avg";
const string FEE_ELECTRIC = "fee_electric";
const string FEE_SERVICE = "fee_service";
const string NUM = "num"; // 充电次数
const string NUM_SUCCESS = "num_success"; // 充电成功次数
const string NUM_FAILED = "num_failed"; // 充电失败次数
}
namespace DMStatChargerData
{
const string TABLENAME = "stat_charger_data";
const string TIME = "collect_time";
const string CHARGER_ID = "charger_id";
const string VOLTAGE = "voltage";
const string CURRENT = "current";
const string POWER = "power";
}
class DaoStat
{
public:
// ************************************************************************************************
static bool insert_charge_curve(DataFields& fields);
static bool query_charge_curve_by_time(string start_time, string end_time, std::vector<DataFields>& result);
static bool query_station_power_by_time(string start_time, string end_time, std::vector<DataFields>& result);
static void insert_charger_data(int t_interval);
/**
* 查询当天的充电机电压、电流、功率历史数据
*/
static bool query_charge_data(std::string dt, vector<DataFields>& result);
};

View File

@@ -0,0 +1,63 @@
#include "DaoSwap.h"
#include "app/Constant.h"
#include "app/Global.h"
#include "common/spdlogger.h"
#include "common/TimeUtils.h"
#include "common/Snowflake.h"
#include "database/DaoEntity.h"
#include "Device.h"
std::string DaoSwap::create_swap_record(std::string biz_id, DeviceSwapEntity* swap_entity)
{
auto& appdata = Global::data();
if (!swap_entity)
{
Spdlogger::error("create swap record failed: swap_entity is null, biz_id={}", biz_id);
return "";
}
swap_entity->info.biz_id = biz_id;
Spdlogger::info("[SWAP] create swap biz record: biz_id={}", swap_entity->info.biz_id);
DataFields fields;
fields.set(DMSwapRecord::ID, swap_entity->info.biz_id);
fields.set(DMSwapRecord::SWAP_MODE, (int)swap_entity->work_mode);
fields.set(DMSwapRecord::BATT_MODEL, swap_entity->info.car_battery_model);
fields.set(DMSwapRecord::CAR_NUM, swap_entity->info.car_no);
fields.set(DMSwapRecord::USER_ID, swap_entity->info.user_id);
fields.set(DMSwapRecord::BATT_DOWN_ID, swap_entity->info.car_batt_code);
fields.set(DMSwapRecord::BATT_ON_ID, swap_entity->info.new_batt_code);
fields.set(DMSwapRecord::BATT_ON_SOC, swap_entity->info.soc);
fields.set(DMSwapRecord::STATUS, swap_entity->info.status);
fields.set(DMSwapRecord::CAUSE, PV::NODE_CAR_VERIFY);
fields.set(DMSwapRecord::OPEN_TIME, TimeUtils::ts2datetime(swap_entity->info.open_time));
DaoEntity dao(DMSwapRecord::TABLENAME);
bool res = dao.insert_fields(fields);
if (!res)
{
Spdlogger::error("create swap record failed: database error, biz_id={}, car_no={}.", swap_entity->info.biz_id, swap_entity->info.car_no);
}
return swap_entity->info.biz_id;
}
int DaoSwap::update_swap_record(std::string biz_id, DataFields& fields)
{
auto& appdata = Global::data();
if (biz_id.empty())
{
Spdlogger::error("[SWAP] update swap data record errorbizid is NULL");
return 0;
}
if (fields.size() > 0)
{
fields.remove(DMSwapRecord::ID);
string sql_c = " where " + DMSwapRecord::ID + "='" + biz_id + "'";
DaoEntity dao(DMSwapRecord::TABLENAME);
dao.update_fields(fields, sql_c);
Global::request_stat = true;
return 1;
}
return 0;
}

View File

@@ -0,0 +1,56 @@
#pragma once
#include "DataFields.h"
class DeviceSwapEntity;
namespace DMSwapRecord
{
const string TABLENAME = "swap_record";
const string ID = "id";
const string USER_ID = "user_id";
const string CAR_NUM = "car_no";
const string SWAP_MODE = "swap_mode";
const string BATT_MODEL = "batt_model";
const string BATT_DOWN_ID = "batt_down_id";
const string BATT_DOWN_SOC = "batt_down_soc";
const string BATT_DOWN_POWER = "batt_down_power";
const string BATT_ON_ID = "batt_on_id";
const string BATT_ON_SOC = "batt_on_soc";
const string BATT_ON_POWER = "batt_on_power";
const string OPEN_TIME = "open_time";
const string CLOSE_TIME = "close_time";
const string START_TIME = "start_time";
const string END_TIME = "end_time";
const string DURATION = "duration";
const string TOTAL_DURATION = "total_duration";
const string STATUS = "status";
const string CAUSE = "cause";
const string FEE_ELECTRICE = "fee_electric";
const string FEE_SERVICE = "fee_service";
const string POWER = "power";
const string CREATE_TIME = "create_time";
const string UPDATE_TIME = "create_time";
}
class DaoSwap
{
public:
/**
* 创建换电业务订单
*/
static std::string create_swap_record(std::string biz_id, DeviceSwapEntity* swap_entity);
/**
* 更新换电业务订单
* @param: [std::string biz_id] 订单号
* @param: [DataFields& fields] 要更新的字段
* @return: [int] 0: 更新失败;其它表示更新成功
*/
static int update_swap_record(std::string biz_id, DataFields& fields);
/**
* 写入换电业务节点状态执行记录
*/
static void insert_swap_node_status();
};

239
src/database/dao/DaoSys.cpp Normal file
View File

@@ -0,0 +1,239 @@
#include "DaoSys.h"
#include "common/Utils.h"
#include "common/Snowflake.h"
#include "Admin.h"
#include "Spdlogger.h"
#include "database/DaoEntity.h"
#include "database/dao/DaoDevice.h"
#include "database/dao/DaoCharge.h"
static void LogDaoResult(std::vector<DataFields>& vec_fields)
{
for (int i = 0; i < vec_fields.size(); i++)
{
string s = "{";
vec_fields[i].foreach_item([&](string key, string val)
{
s += (key + ":" + val + ", ");
});
s = s.substr(0, s.size() - 2);
s += "}";
}
}
int DaoSys::insert_price(DataFields& fields)
{
fields.remove(DMPrice::FID_CREATE_TIME);
fields.remove(DMPrice::FID_UPDATE_TIME);
DaoEntity dao(DMPrice::TABLENAME);
return dao.insert_fields(fields);
}
bool DaoSys::query_price(PageInfo& pageinfo, vector<DataFields>& result, string sql_c)
{
DaoEntity dao(DMPrice::TABLENAME);
return dao.query_fields("*", sql_c, pageinfo, result);
}
bool DaoSys::update_price(DataFields& fields, const string& sql_c)
{
fields.remove(DMPrice::FID_ID);
fields.remove(DMPrice::FID_CREATE_TIME);
fields.remove(DMPrice::FID_UPDATE_TIME);
DaoEntity dao(DMPrice::TABLENAME);
return dao.update_fields(fields, sql_c);
}
bool DaoSys::update_price_attr(vector<DataFields>& vec_fields)
{
DaoEntity dao(DMPriceAttr::TABLENAME);
bool ret = true;
std::vector<DataFields> result;
string sql = "";
for (auto& item : vec_fields)
{
item.remove("id");
string price_id = item.get_str(DMPriceAttr::FID_PRICE_ID);
if (!sql.empty())
{
sql += ",";
}
sql += ("'" + price_id + "'");
}
sql = "delete from " + DMPriceAttr::TABLENAME + " where " + DMPriceAttr::FID_PRICE_ID + " in (" + sql + ")";
dao.exec(sql);
dao.insert_fields(vec_fields);
return ret;
}
void DaoSys::insert_sec_warn(DataFields& fields)
{
// 生成告警示例
//DaoSecLog::DataModel d;
//d.id = Snowflake::instance().nextIdString(); // ID
//d.ts; // 告警时间
//d.type; // 告警类型: 1:站控系统类 2:换电设备类 3:充电机类 4:辅助设备类
//d.level = 1; // 告警级别: L1 ~ L4
//d.content; // 告警内容
//d.device_id; // 设备ID
//d.status = 1; // 当前状态
DaoEntity dao(DMSecRecord::TABLENAME);
dao.insert_fields(fields);
}
int DaoSys::update_sec_warn(string id, int status)
{
DataFields fields;
//d.add(DaoSecLog::FID_ID, "");
fields.set(DMSecRecord::DISPOSE_USER, Admin::instance().optor().name);
fields.set(DMSecRecord::DISPOSE_TIME, Utils::time_now_string());
fields.set(DMSecRecord::STATUS, to_string(status)); // 当前状态 0: 已复位 1: 未处理 2: --
DaoEntity dao(DMSecRecord::TABLENAME);
return dao.update_fields(fields, "where id='" + id + "'");
}
int DaoSys::insert_message_log(DataFields& fields)
{
string date;
string time = fields.get_str(DMMessageLog::FID_CREATE_TIME);
if (time.size() < 10)
{
Spdlogger::error("[DB] Message log time error: time={}, set table name date={}", time, date);
date = Utils::time_now_string().substr(0, 10);
}
else
{
date = time.substr(0, 10);
}
string tbname = DMMessageLog::TABLENAME + date;
string dll_sql = "CREATE TABLE IF NOT EXISTS `" + tbname + "` " + DMMessageLog::DDL;
bool ret = DaoEntity::exec_once(dll_sql.c_str());
if (!ret)
{
Spdlogger::error("[DB] Message log create table failed: {}", dll_sql);
return 0;
}
DaoEntity::exec_once(fields.get_insert_sql(tbname).c_str());
return 1;
}
bool DaoSys::query_system_info(std::vector<DataFields>& result)
{
DaoEntity dao(DMSystemInfo::TABLENAME);
return dao.query_fields("*", "", result);
}
bool DaoSys::insert_ammeter_data(DataFields& fields)
{
DaoEntity dao(DMDeviceDataRecord::TABLENAME);
return dao.insert_fields(fields);
}
int DaoSys::insert_sec_policy(DataFields& fields)
{
DaoEntity dao(DMSecPolicy::TABLENAME);
return dao.insert_fields(fields);
}
bool DaoSys::query_sec_policy(PageInfo& pageinfo, vector<DataFields>& result, string sql_c)
{
DaoEntity dao(DMSecPolicy::TABLENAME);
return dao.query_fields("*", sql_c, pageinfo, result);
}
bool DaoSys::update_sec_policy_by_id(DataFields& fields)
{
string id = fields.get_str(DMSecPolicy::FID_ID);
fields.remove(DMSecPolicy::FID_ID);
DaoEntity dao(DMSecPolicy::TABLENAME);
return dao.update_fields(fields, "where " + DMSecPolicy::FID_ID + "='" + id + "'");
}
bool DaoSys::insert_sec_record(DataFields& fields)
{
DaoEntity dao(DMSecRecord::TABLENAME);
return dao.insert_fields(fields);
}
bool DaoSys::query_sec_record(PageInfo& pageinfo, vector<DataFields>& result, string sql_c)
{
DaoEntity dao(DMSecRecord::TABLENAME);
return dao.query_fields("*", sql_c, pageinfo, result);
}
bool DaoSys::update_sec_record(DataFields& fields, const string& sql_c)
{
DaoEntity dao(DMSecRecord::TABLENAME);
return dao.update_fields(fields, sql_c);
}
int DaoSys::insert_service(DataFields& fields)
{
fields.remove(DMService::FID_CREATE_TIME);
fields.remove(DMService::FID_UPDATE_TIME);
DaoEntity dao(DMService::TABLENAME);
return dao.insert_fields(fields);
}
bool DaoSys::query_service(PageInfo& pageinfo, vector<DataFields>& result, string sql_c)
{
DaoEntity dao(DMService::TABLENAME);
return dao.query_fields("*", sql_c, pageinfo, result);
}
bool DaoSys::update_service(DataFields& fields, const string& sql_c)
{
fields.remove(DMService::FID_INTERFACE_NAME);
fields.remove(DMService::FID_CREATE_TIME);
fields.remove(DMService::FID_UPDATE_TIME);
DaoEntity dao(DMService::TABLENAME);
return dao.update_fields(fields, sql_c);
}
int DaoSys::insert_serv_history(DataFields& fields)
{
fields.remove(DMServHistory::FID_CREATE_TIME);
DaoEntity dao(DMServHistory::TABLENAME);
return dao.insert_fields(fields);
}
bool DaoSys::query_serv_history(PageInfo& pageinfo, vector<DataFields>& result, string sql_c)
{
DaoEntity dao(DMServHistory::TABLENAME);
return dao.query_fields("*", sql_c, pageinfo, result);
}
bool DaoSys::update_serv_history(DataFields& fields, const string& sql_c)
{
fields.remove(DMServHistory::FID_ID);
fields.remove(DMServHistory::FID_CREATE_TIME);
DaoEntity dao(DMServHistory::TABLENAME);
return dao.update_fields(fields, sql_c);
}
int DaoSys::insert_syslog(string logtype, string optor, string device_id, string msg)
{
DataFields fields;
fields.set(DMSystemLog::FID_ID, Snowflake::instance().next_id_str());
fields.set(DMSystemLog::FID_TYPE, logtype);
fields.set(DMSystemLog::FID_USER_ID, optor);
fields.set(DMSystemLog::FID_DEVICE_ID, device_id);
fields.set(DMSystemLog::FID_MSG, msg);
DaoEntity dao(DMSystemLog::TABLENAME);
dao.insert_fields(fields);
return 0;
}

192
src/database/dao/DaoSys.h Normal file
View File

@@ -0,0 +1,192 @@
#pragma once
#include <vector>
#include "DataFields.h"
namespace DMPrice
{
const string TABLENAME = "price";
const string FID_ID = "id";
const string FID_NAME = "name";
const string FID_TYPE = "type";
const string FID_EFFECTIVE_TIME = "effective_time";
const string FID_EXPIRE_TIME = "expire_time";
const string FID_IS_OPEN = "is_open";
const string FID_CREATE_TIME = "create_time";
const string FID_UPDATE_TIME = "update_time";
}
namespace DMPriceAttr
{
const string TABLENAME = "price_attr";
const string FID_PRICE_ID = "price_id";
const string FID_TYPE = "type";
const string FID_START_TIME = "start_time";
const string FID_END_TIME = "end_time";
const string FID_VALUE = "value";
}
namespace DMSecPolicy
{
const string TABLENAME = "sec_policy";
const string FID_ID = "id";
const string FID_SEC_TYPE = "sec_type";
const string FID_EVENT_NAME = "event_name";
const string FID_EVENT_CODE = "event_code";
const string FID_LEVEL = "level";
const string FID_IS_OPEN = "is_open";
const string FID_REMARK = "remark";
const string FID_ACTION = "action";
const string FID_TEXT = "text";
const string FID_VOICE = "voice";
}
namespace DMSecRecord
{
const string TABLENAME = "sec_record";
const string ID = "id";
const string TIME = "warn_time";
const string TYPE = "type";
const string LEVEL = "level";
const string CONTENT = "content";
const string POLICY_ID = "policy_id";
const string DEVICE_ID = "device_id";
const string USER = "user";
const string DISPOSE_USER = "dispose_user";
const string DISPOSE_TIME = "dispose_time";
const string PROCESS_MODE = "process_mode";
const string STATUS = "status";
}
namespace DMSystemInfo
{
const string TABLENAME = "system_info";
const string FID_STATION_NAME = "station_name";
const string FID_ACTIVATION_TIME = "activation_time";
const string FID_WORK_MODE = "swap_mode";
}
namespace DMService
{
const string TABLENAME = "service_monitor";
const string FID_INTERFACE_NAME = "interface_name";
const string FID_PROTOCOL_TYPE = "protocol_type";
const string FID_REPORT_TYPE = "report_type";
const string FID_REPORT_CYCLE = "report_cycle";
const string FID_REMARK = "remark";
const string FID_IS_OPEN = "is_open";
const string FID_CREATE_TIME = "create_time";
const string FID_UPDATE_TIME = "update_time";
}
namespace DMServHistory
{
const string TABLENAME = "service_history";
const string FID_ID = "id";
const string FID_SERV_ID = "service_id";
const string FID_DATA_NUM = "data_num";
const string FID_SUCCESS_NUM = "success_num";
const string FID_FAILURE_NUM = "failure_num";
const string FID_REQ_TIME = "req_time";
const string FID_RES_TIME = "res_time";
const string FID_CREATE_TIME = "create_time";
}
namespace DMSystemLog
{
const string TABLENAME = "system_log";
const string FID_ID = "id";
const string FID_TYPE = "type";
const string FID_USER_ID = "user_id";
const string FID_DEVICE_ID = "device_id";
const string FID_MSG = "msg";
const string FID_CREATE_TIME = "create_time";
const string FID_UPDATE_TIME = "update_time";
}
// 报文日志
namespace DMMessageLog
{
// 表名称根据日期改变(日期作为后缀: message_log2023-01-01
const string TABLENAME = "message_log";
const string DDL = R"((
`id` varchar(32) NOT NULL COMMENT 'ID',
`device_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'ID',
`create_time` datetime NOT NULL COMMENT '',
`type` int DEFAULT NULL COMMENT ', 12',
`function` varchar(60) DEFAULT NULL,
`data` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '',
`status` int DEFAULT NULL COMMENT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;)";
const string FID_ID = "id";
const string FID_DEVICE_ID = "device_id";
const string FID_CREATE_TIME = "create_time";
const string FID_TYPE = "type"; // 1: 发送2接收
const string FID_FUNCTION = "function";
const string FID_DATA = "data";
const string FID_STATUS = "status";
}
class DaoSys
{
public:
// ************************************************************************************************
// 计费管理
static int insert_price(DataFields& fields);
static bool query_price(PageInfo& pageinfo, vector<DataFields>& result, string sql_c);
static bool update_price(DataFields& fields, const string& sql_c);
static bool update_price_attr(vector<DataFields>& vec_fields);
static void insert_sec_warn(DataFields& fields);
static int update_sec_warn(string id, int status);
// ************************************************************************************************
// 报文管理
static int insert_message_log(DataFields& fields);
static bool query_system_info(std::vector<DataFields>& result);
// ************************************************************************************************
// 电表采集数据
// 写入电表采集的数据
static bool insert_ammeter_data(DataFields& fields);
// ************************************************************************************************
// 安全策略
static int insert_sec_policy(DataFields& fields);
static bool query_sec_policy(PageInfo& pageinfo, vector<DataFields>& result, string sql_c);
static bool update_sec_policy_by_id(DataFields& fields);
// ************************************************************************************************
// 安全运行记录
static bool insert_sec_record(DataFields& fields);
static bool query_sec_record(PageInfo& pageinfo, vector<DataFields>& result, string sql_c);
static bool update_sec_record(DataFields& fields, const string& sql_c);
// ************************************************************************************************
// 服务管理
static int insert_service(DataFields& fields);
static bool query_service(PageInfo& pageinfo, vector<DataFields>& result, string sql_c);
static bool update_service(DataFields& fields, const string& sql_c);
// ************************************************************************************************
// 服务管理历史记录
static int insert_serv_history(DataFields& fields);
static bool query_serv_history(PageInfo& pageinfo, vector<DataFields>& result, string sql_c);
static bool update_serv_history(DataFields& fields, const string& sql_c);
// ************************************************************************************************
// 日志管理
static int insert_syslog(string logtype, string optor, string device_id, string msg);
};

View File

@@ -0,0 +1,45 @@
#include "DaoUser.h"
#include "database/DaoEntity.h"
#include "common/Snowflake.h"
bool DaoUser::insert_user(DataFields& fields)
{
fields.check(DMAccount::BALANCE, "", "0");
fields.check(DMAccount::STATUS, "", "NULL");
fields.check(DMAccount::TYPE, "", "NULL");
fields.remove(DMAccount::CREATE_TIME);
fields.remove(DMAccount::UPDATE_TIME);
fields.set(DMAccount::USER_ID, "U" + Snowflake::instance().next_id_str());
DaoEntity dao(DMAccount::TABLENAME);
return dao.insert_fields(fields);
}
bool DaoUser::update_user(std::string user_id, DataFields& fields)
{
fields.check(DMAccount::BALANCE, "", "0");
fields.check(DMAccount::STATUS, "", "NULL");
fields.check(DMAccount::TYPE, "", "NULL");
fields.remove(DMAccount::USER_ID);
fields.remove(DMAccount::CREATE_TIME);
fields.remove(DMAccount::UPDATE_TIME);
DaoEntity dao(DMAccount::TABLENAME);
string sql_c = "where " + DMAccount::USER_ID + "='" + user_id + "'";
return dao.update_fields(fields, sql_c);
}
bool DaoUser::query_user(PageInfo& pageinfo, vector<DataFields>& result, string sql_c/*=""*/)
{
// 查询数据库
DaoEntity dao(DMAccount::TABLENAME);
return dao.query_fields("*", sql_c, pageinfo, result);
}
bool DaoUser::query_user_by_car_num(string car_num, vector<DataFields>& result)
{
string sql = "SELECT car.id, car.car_no, car.brand, car.model, car.battery_model, car.batt_code, battery.model batt_model, battery.lock_type,"
"account.user_id, account.name, account.phone, account.balance FROM car "
"LEFT JOIN battery ON battery.code=car.batt_code "
"LEFT JOIN account ON account.user_id=car.user_id "
"where car_no = '" + car_num + "';";
return DaoEntity::exec_once(sql, result);
}

View File

@@ -0,0 +1,68 @@
#pragma once
#include "DataFields.h"
/**
* 用户表结构字段
*/
namespace DMUser
{
const string USER_ID = "user_id";
const string ACCOUNT_ID = "account_id";
const string FID_NAME = "name";
const string FID_PHONE = "phone";
const string FIELD_GENDER = "gender";
const string FIELD_AGE = "age";
const string CREATETIME = "create_time";
const string UPDATETIME = "update_time";
}
/**
* 用户账户表结构字段
*/
namespace DMAccount
{
const string TABLENAME = "account"; // 表名称
const string USER_ID = "user_id"; // 用户ID
const string ACCOUNT = "account"; // 账户名称
const string NAME = "name"; // 用户姓名
const string PHONE = "phone"; // 手机号
const string GENDER = "gender"; // 性别
const string STATUS = "status"; // 状态
const string TYPE = "type"; // 类型
const string BALANCE = "balance"; // 余额
const string CREATE_TIME = "create_time";
const string UPDATE_TIME = "update_time";
}
class DaoUser
{
public:
/**
* 创建新的用户
* @param: [DataFields& fields] 用户信息
*/
static bool insert_user(DataFields& fields);
/**
* 更新用户账户信息更新条件user_id
* @param: [std::string user_id] 用户ID
* @param: [DataFields& fields] 用户信息
*/
static bool update_user(std::string user_id, DataFields& fields);
/**
* 查询用户信息
* @param: [PageInfo& pageinfo] 分页设置
* @param: [vector<DataFields>& result] 查询结果集
* @param: [string sql_c] 查询条件where id='1'
*/
static bool query_user(PageInfo& pageinfo, vector<DataFields>& result, string sql_c = "");
/**
* 根据车牌号码查询用户信息(需要联合用户表和车辆信息表)
* @param: [string car_num] 车牌号
* @param: [vector<DataFields>& result] 查询结果集
*/
static bool query_user_by_car_num(string car_num, vector<DataFields>& result);
};