mirror of
https://gitee.com/js-yhsec/energy_storage.git
synced 2026-05-27 18:59:26 +08:00
上传项目代码
This commit is contained in:
60
src/CMakeLists.txt
Normal file
60
src/CMakeLists.txt
Normal file
@@ -0,0 +1,60 @@
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
|
||||
set(PROJECT_NAME EES)
|
||||
project(${PROJECT_NAME})
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# 【注意】visual studio编译时的字符编码问题,配置属性 --> C/C++ --> 命令行 --> 其它选项: /utf-8 或添加如下指令
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8")
|
||||
|
||||
# Qt_PATH 为 Qt 的安装地址
|
||||
set(QT_PATH "D:/Programs/Qt5/5.15.2/msvc2019_64")
|
||||
set(CMAKE_PREFIX_PATH ${QT_PATH}/lib/cmake)
|
||||
|
||||
|
||||
# 开启自动编译
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
find_package(Qt5 COMPONENTS Widgets AxContainer Network SerialBus SerialPort Charts WebEngineWidgets REQUIRED)
|
||||
|
||||
add_definitions(-DWIN32_LEAN_AND_MEAN)
|
||||
|
||||
set(ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(THIRDPARTY_PATH ${ROOT_PATH}/../thirdparty)
|
||||
|
||||
include_directories(
|
||||
${ROOT_PATH}
|
||||
${ROOT_PATH}/app
|
||||
${ROOT_PATH}/common
|
||||
${ROOT_PATH}/widgets
|
||||
${THIRDPARTY_PATH}
|
||||
${THIRDPARTY_PATH}/mysql/include
|
||||
)
|
||||
|
||||
macro(ADD_SOURCE_GROUP srcpath)
|
||||
file(GLOB src_h ${PROJECT_SOURCE_DIR}/${srcpath}/*.h)
|
||||
file(GLOB src_cpp ${PROJECT_SOURCE_DIR}/${srcpath}/*.cpp)
|
||||
set(src_tmp ${src_h} ${src_cpp})
|
||||
source_group(src/${srcpath} FILES ${src_tmp})
|
||||
list(APPEND SOURCE_FILE ${src_tmp})
|
||||
endmacro(ADD_SOURCE_GROUP)
|
||||
|
||||
# 设置编译源文件
|
||||
ADD_SOURCE_GROUP(./)
|
||||
ADD_SOURCE_GROUP(common)
|
||||
ADD_SOURCE_GROUP(app)
|
||||
ADD_SOURCE_GROUP(database)
|
||||
ADD_SOURCE_GROUP(protocol)
|
||||
ADD_SOURCE_GROUP(widgets)
|
||||
ADD_SOURCE_GROUP(widgets/pages)
|
||||
|
||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../bin)
|
||||
add_executable(${PROJECT_NAME} ${SOURCE_FILE})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} Qt5::Widgets Qt5::AxContainer Qt5::Network Qt5::SerialBus Qt5::SerialPort Qt5::Charts Qt5::WebEngineWidgets)
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
ws2_32 iphlpapi
|
||||
${THIRDPARTY_PATH}/mysql/lib/x64/libmysql.lib
|
||||
)
|
||||
0
src/app/AppSetting.cpp
Normal file
0
src/app/AppSetting.cpp
Normal file
12
src/app/AppSetting.h
Normal file
12
src/app/AppSetting.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
class AppSetting
|
||||
{
|
||||
public:
|
||||
static AppSetting& instance() {
|
||||
static AppSetting inst;
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
21
src/app/Application.cpp
Normal file
21
src/app/Application.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "Application.h"
|
||||
|
||||
#include "common/Utils.h"
|
||||
|
||||
void Application::init()
|
||||
{
|
||||
std::thread([=]()
|
||||
{
|
||||
while (!isQuit()) { runThreadMain(); }
|
||||
}).detach();
|
||||
}
|
||||
|
||||
void Application::runThreadMain()
|
||||
{
|
||||
static TimeTick tt;
|
||||
tt.elapse(1000);
|
||||
|
||||
//XLOGD() << "HelloWorld";
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
28
src/app/Application.h
Normal file
28
src/app/Application.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <thread>
|
||||
#include "common/Logger.h"
|
||||
|
||||
#include "Operator.h"
|
||||
|
||||
class Application
|
||||
{
|
||||
public:
|
||||
static Application& instance()
|
||||
{
|
||||
static Application app;
|
||||
return app;
|
||||
}
|
||||
|
||||
void init();
|
||||
bool isQuit() { return isQuit_; }
|
||||
Operator& getOperator() { return op_; }
|
||||
|
||||
void runThreadMain();
|
||||
|
||||
private:
|
||||
bool isQuit_ = false;
|
||||
|
||||
// 登录的管理员信息
|
||||
Operator op_;
|
||||
};
|
||||
147
src/app/Dao.cpp
Normal file
147
src/app/Dao.cpp
Normal file
@@ -0,0 +1,147 @@
|
||||
#include "Dao.h"
|
||||
#include "common/Logger.h"
|
||||
#include "common/Utils.h"
|
||||
#include "common/Snowflake.h"
|
||||
|
||||
enum class EnDatabaseErr
|
||||
{
|
||||
SUCCESS = 0,
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
std::string t = Utils::timeNowStr();
|
||||
if (!dao)
|
||||
{
|
||||
dao = std::make_shared<DaoEntity>("");
|
||||
}
|
||||
if (!dao->isConnected())
|
||||
{
|
||||
err = "数据库连接错误";
|
||||
DAO::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string sql = "SELECT * FROM user WHERE account='" + account + "';";
|
||||
|
||||
std::vector<DataFields> res;
|
||||
bool ret = dao->exec(sql, res);
|
||||
if (!ret)
|
||||
{
|
||||
err = "数据库操作错误";
|
||||
DAO::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
|
||||
return false;
|
||||
}
|
||||
if (res.size() <=0)
|
||||
{
|
||||
err = "用户不存在";
|
||||
DAO::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
|
||||
return false;
|
||||
}
|
||||
DataFields& fields = res[0];
|
||||
std::string userId = fields.get_str("user_id");
|
||||
int loginCount = fields.get_int("login_count");
|
||||
|
||||
// 判断密码
|
||||
if (passwd != fields.get_str("passwd"))
|
||||
{
|
||||
err = "密码错误";
|
||||
DAO::writeSystemLog(dao, 2, userId, account, "用户登录失败:" + err);
|
||||
return false;
|
||||
}
|
||||
|
||||
err = "登录成功";
|
||||
|
||||
// 数据库更新用户登录信息
|
||||
sql = "UPDATE user SET login_time='" + t + "', login_count='" + std::to_string(loginCount + 1) + "' WHERE user_id = '" + userId + "'; ";
|
||||
ret = dao->exec(sql);
|
||||
if (!ret)
|
||||
{
|
||||
XLOGE() << "更新用户登录信息失败:sql=" << sql;
|
||||
}
|
||||
|
||||
DAO::writeSystemLog(dao, 2, userId, account, "用户登录成功");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DAO::writeSystemLog(std::shared_ptr<DaoEntity> dao, int type, std::string userId, std::string account, std::string text)
|
||||
{
|
||||
if (!dao)
|
||||
{
|
||||
dao = std::make_shared<DaoEntity>("");
|
||||
}
|
||||
if (!dao->isConnected())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 数据库写入登录日志
|
||||
dao->setTableName("system_log");
|
||||
DataFields fieldsLog;
|
||||
fieldsLog.set("id", Snowflake::instance().nextIdStr());
|
||||
fieldsLog.set("type", 2);
|
||||
fieldsLog.set("user_id", userId);
|
||||
fieldsLog.set("user_account", account);
|
||||
fieldsLog.set("content", text);
|
||||
fieldsLog.set("log_time", Utils::timeNowStr());
|
||||
bool ret = dao->insertFields({fieldsLog});
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool DAO::queryUser(std::vector<DataFields>& res)
|
||||
{
|
||||
std::shared_ptr<DaoEntity> dao = std::make_shared<DaoEntity>("");
|
||||
if (!dao->isConnected())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
std::string sql = "SELECT u.*, r.role_id, r.name role_name from USER u LEFT JOIN user_role ur ON u.user_id = ur.user_id LEFT JOIN `role` r ON r.role_id = ur.role_id;";
|
||||
bool ret = dao->exec(sql, res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DAO::insertUser(DataFields& fields)
|
||||
{
|
||||
std::shared_ptr<DaoEntity> dao = std::make_shared<DaoEntity>("user");
|
||||
if (!dao->isConnected())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string account = fields.get_str("account");
|
||||
|
||||
// step1: 查询
|
||||
std::vector<DataFields> res;
|
||||
bool ret = dao->exec("SELECT * from user WHERE account='" + account + "';", res);
|
||||
if (!ret)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (res.size() > 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
fields.set("user_id", Snowflake::instance().nextIdStr());
|
||||
fields.set("create_time", Utils::timeNowStr());
|
||||
ret = dao->insertFields(fields);
|
||||
return (ret) ? 0 : 1;
|
||||
}
|
||||
|
||||
int DAO::updateUserById(std::string id, DataFields& fields)
|
||||
{
|
||||
std::shared_ptr<DaoEntity> dao = std::make_shared<DaoEntity>("user");
|
||||
if (!dao->isConnected())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
string sqlC = "WHERE user_id='" + id + "'";
|
||||
bool ret = dao->updateFields(fields, sqlC);
|
||||
return (ret) ? 0 : 1;
|
||||
}
|
||||
30
src/app/Dao.h
Normal file
30
src/app/Dao.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "database/DaoEntity.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 bool writeSystemLog(std::shared_ptr<DaoEntity> dao, int type, std::string userId, std::string account, std::string text);
|
||||
|
||||
|
||||
// =======================================================================
|
||||
// 用户管理数据操作
|
||||
|
||||
/**
|
||||
* 查询用户
|
||||
*/
|
||||
static bool queryUser(std::vector<DataFields>& res);
|
||||
|
||||
/**
|
||||
* 新增用户
|
||||
*/
|
||||
static int insertUser(DataFields& fields);
|
||||
|
||||
/**
|
||||
* 修改用户信息
|
||||
*/
|
||||
static int updateUserById(std::string id, DataFields& fields);
|
||||
};
|
||||
0
src/app/Device.cpp
Normal file
0
src/app/Device.cpp
Normal file
7
src/app/Device.h
Normal file
7
src/app/Device.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
class Device
|
||||
{
|
||||
public:
|
||||
static bool init();
|
||||
};
|
||||
18
src/app/Operator.cpp
Normal file
18
src/app/Operator.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#include "Operator.h"
|
||||
#include "DAO.h"
|
||||
#include "common/Logger.h"
|
||||
|
||||
bool Operator::login(std::string account, std::string passwd, std::string& err)
|
||||
{
|
||||
bool ret = DAO::login(nullptr, account, passwd, err);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
XLOGD() << "用户[" + account + "]登录成功";
|
||||
}
|
||||
else
|
||||
{
|
||||
XLOGD() << "用户[" + account + "]登录失败: " << err;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
16
src/app/Operator.h
Normal file
16
src/app/Operator.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class Operator
|
||||
{
|
||||
public:
|
||||
bool login(std::string account, std::string passwd, std::string& err);
|
||||
|
||||
bool logout(std::string& err);
|
||||
|
||||
|
||||
std::string account_;
|
||||
std::string passwd_;
|
||||
|
||||
};
|
||||
10
src/cmake_msvc2019.bat
Normal file
10
src/cmake_msvc2019.bat
Normal file
@@ -0,0 +1,10 @@
|
||||
cd %~dp0
|
||||
|
||||
cd ..
|
||||
@REM rd /S /Q .build
|
||||
mkdir #buildmsvc2019
|
||||
cd #buildmsvc2019
|
||||
|
||||
@REM Visual Studio 16 2019/Visual Studio 17 2022
|
||||
@REM Win32/x64
|
||||
cmake ../src -G "Visual Studio 16 2019" -A x64
|
||||
197
src/common/DataFields.cpp
Normal file
197
src/common/DataFields.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
#include "DataFields.h"
|
||||
#include "common/Utils.h"
|
||||
|
||||
void DataFields::set(string key, string val)
|
||||
{
|
||||
map_fields_[key] = val;
|
||||
}
|
||||
void DataFields::set(string key, float val)
|
||||
{
|
||||
map_fields_[key] = std::to_string(val);
|
||||
}
|
||||
void DataFields::set(string key, int val)
|
||||
{
|
||||
map_fields_[key] = std::to_string(val);
|
||||
}
|
||||
void DataFields::set(string key, int64_t val)
|
||||
{
|
||||
map_fields_[key] = std::to_string(val);
|
||||
}
|
||||
string DataFields::get_str(string key)
|
||||
{
|
||||
if (map_fields_.count(key) > 0)
|
||||
{
|
||||
return map_fields_[key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
int DataFields::get_int(string key)
|
||||
{
|
||||
return map_fields_.count(key) > 0 ? Utils::toInt(map_fields_[key]) : 0;
|
||||
}
|
||||
float DataFields::get_float(string key)
|
||||
{
|
||||
return map_fields_.count(key) > 0 ? Utils::toFloat(map_fields_[key]) : 0.0f;
|
||||
}
|
||||
void DataFields::remove(string key)
|
||||
{
|
||||
auto it = map_fields_.find(key);
|
||||
if (it != map_fields_.end())
|
||||
{
|
||||
map_fields_.erase(it);
|
||||
}
|
||||
}
|
||||
void DataFields::append(DataFields& datafield)
|
||||
{
|
||||
auto& map_f = datafield.fields();
|
||||
for (auto it = map_f.begin(); it != map_f.end(); it++)
|
||||
{
|
||||
map_fields_[it->first] = it->second;
|
||||
}
|
||||
}
|
||||
map<string, string>& DataFields::fields()
|
||||
{
|
||||
return map_fields_;
|
||||
}
|
||||
|
||||
void DataFields::check(string key, string val, string d)
|
||||
{
|
||||
if (map_fields_.count(key) > 0 && map_fields_[key] == val)
|
||||
{
|
||||
map_fields_[key] = d;
|
||||
}
|
||||
}
|
||||
|
||||
string DataFields::get_insert_sql(string tbname)
|
||||
{
|
||||
string key;
|
||||
string val;
|
||||
for (auto it = map_fields_.begin(); it != map_fields_.end(); it++)
|
||||
{
|
||||
if (!key.empty())
|
||||
{
|
||||
key += ",";
|
||||
val += ",";
|
||||
}
|
||||
key += ("`" + it->first + "`");
|
||||
if (it->second == "null" || it->second == "NULL")
|
||||
{
|
||||
val += "NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
val += ("'" + it->second + "'");
|
||||
}
|
||||
}
|
||||
return "INSERT INTO `" + tbname + "` (" + key + ") VALUES(" + val + ");";
|
||||
}
|
||||
|
||||
string DataFields::get_update_sql(string tbname, string sql_c)
|
||||
{
|
||||
ostringstream oss;
|
||||
oss << "update " << tbname << " set ";
|
||||
for (auto iter = map_fields_.begin(); iter != map_fields_.end(); iter++)
|
||||
{
|
||||
if (iter != map_fields_.begin())
|
||||
{
|
||||
oss << ",";
|
||||
};
|
||||
oss << "`" << iter->first << "`=";
|
||||
if (iter->second == "null" || iter->second == "NULL")
|
||||
{
|
||||
oss << "NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "'" << iter->second << "'";
|
||||
}
|
||||
}
|
||||
oss << " " << sql_c << ";";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
string DataFields::get_update_sql(string tbname, std::vector<std::string> vec_keys, string sql_c)
|
||||
{
|
||||
std::map<std::string, bool> map_keys;
|
||||
for (auto& k : vec_keys) { map_keys[k] = true; }
|
||||
|
||||
ostringstream oss;
|
||||
oss << "update " << tbname << " set ";
|
||||
for (auto iter = map_fields_.begin(); iter != map_fields_.end(); iter++)
|
||||
{
|
||||
auto& k = iter->first;
|
||||
auto& v = iter->second;
|
||||
if (!map_keys[k]) { continue; }
|
||||
if (iter != map_fields_.begin())
|
||||
{
|
||||
oss << ",";
|
||||
};
|
||||
oss << "`" << k << "`=";
|
||||
if (v == "null" || v == "NULL")
|
||||
{
|
||||
oss << "NULL";
|
||||
}
|
||||
else
|
||||
{
|
||||
oss << "'" << v << "'";
|
||||
}
|
||||
}
|
||||
oss << " " << sql_c << ";";
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void DataFields::foreach_item(function<void(string key, string val)> on_foraach)
|
||||
{
|
||||
for (auto it = map_fields_.begin(); it != map_fields_.end(); it++)
|
||||
{
|
||||
if (on_foraach)
|
||||
{
|
||||
on_foraach(it->first, it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
bool DataFields::is_empty(string key)
|
||||
{
|
||||
auto& s = map_fields_[key];
|
||||
return s.empty();
|
||||
}
|
||||
|
||||
bool DataFields::is_float_number(string key)
|
||||
{
|
||||
auto& s = map_fields_[key];
|
||||
if (s.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (auto& c : s)
|
||||
{
|
||||
if (std::isdigit(c) == 0 && c != '.')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
string DataFields::to_str()
|
||||
{
|
||||
string s;
|
||||
for (auto it = map_fields_.begin(); it != map_fields_.end(); it++)
|
||||
{
|
||||
s += ("[" + it->first + ":" + it->second + "] ");
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int DataFields::size()
|
||||
{
|
||||
return map_fields_.size();
|
||||
}
|
||||
|
||||
void DataFields::clear()
|
||||
{
|
||||
map_fields_.clear();
|
||||
}
|
||||
149
src/common/DataFields.h
Normal file
149
src/common/DataFields.h
Normal file
@@ -0,0 +1,149 @@
|
||||
#ifndef _DataFields_H_
|
||||
#define _DataFields_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
using namespace std;
|
||||
|
||||
struct PageInfo
|
||||
{
|
||||
int total = 0;
|
||||
int page_id = 1;
|
||||
int page_size = 10;
|
||||
int page_max = 0;
|
||||
};
|
||||
|
||||
class DataFields
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* 设置索引名称和值
|
||||
* @param: [string key] 索引名称
|
||||
* @param: [string val] 值
|
||||
*/
|
||||
void set(string key, string val);
|
||||
|
||||
/**
|
||||
* 设置索引名称和值
|
||||
* @param: [string key] 索引名称
|
||||
* @param: [float val] 值
|
||||
*/
|
||||
void set(string key, float val);
|
||||
|
||||
/**
|
||||
* 设置索引名称和值
|
||||
* @param: [string key] 索引名称
|
||||
* @param: [int val] 值
|
||||
*/
|
||||
void set(string key, int val);
|
||||
|
||||
/**
|
||||
* 设置索引名称和值
|
||||
* @param: [string key] 索引名称
|
||||
* @param: [int64_t val] 值
|
||||
*/
|
||||
void set(string key, int64_t val);
|
||||
|
||||
/**
|
||||
* 获取 string 值
|
||||
* @param: [string key] 索引名称
|
||||
*/
|
||||
string get_str(string key);
|
||||
|
||||
/**
|
||||
* 获取 int 值
|
||||
* @param: [string key] 索引名称
|
||||
*/
|
||||
int get_int(string key);
|
||||
|
||||
/**
|
||||
* 获取 float 值
|
||||
* @param: [string key] 索引名称
|
||||
*/
|
||||
float get_float(string key);
|
||||
|
||||
/**
|
||||
* 删除指定索引的值
|
||||
* @param: [string key] 索引名称
|
||||
*/
|
||||
void remove(string key);
|
||||
|
||||
/**
|
||||
* 追加合并
|
||||
* @param: [DataFields& fields] 要合并的数据
|
||||
*/
|
||||
void append(DataFields& fields);
|
||||
|
||||
/**
|
||||
* 获取数据项map
|
||||
*/
|
||||
map<string, string>& fields();
|
||||
|
||||
/**
|
||||
* 检查某一数据项的值进行替换,如果该项的值是val,则替换成成d
|
||||
* @param: [string key] 索引名称
|
||||
* @param: [string val] 要检查的值
|
||||
* @param: [string d] 替换的值
|
||||
*/
|
||||
void check(string key, string val, string d);
|
||||
|
||||
/**
|
||||
* 转换成插入数据的 sql 语句
|
||||
* @param: [string tbname] 数据表名称
|
||||
*/
|
||||
string get_insert_sql(string tbname);
|
||||
|
||||
/**
|
||||
* 转换成更新数据的 sql 语句
|
||||
* @param: [string tbname] 数据表名称
|
||||
* @param: [string sql_c] sql的更新条件,例如: where id='1'
|
||||
*/
|
||||
string get_update_sql(string tbname, string sql_c);
|
||||
|
||||
|
||||
/**
|
||||
* 转换成更新数据的 sql 语句
|
||||
* @param: [string tbname] 数据表名称
|
||||
* @param: [string vec_keys] 需要更新的字段名称
|
||||
* @param: [string sql_c] sql的更新条件,例如: where id='1'
|
||||
*/
|
||||
string get_update_sql(string tbname, std::vector<std::string> vec_keys, string sql_c);
|
||||
|
||||
/**
|
||||
* 遍历数据项
|
||||
* @param: [function... on_foraach] 回调函数
|
||||
*/
|
||||
void foreach_item(function<void(string key, string val)> on_foraach);
|
||||
|
||||
/**
|
||||
* 判断是否含有数据项
|
||||
* @param: [string key] 索引名称
|
||||
*/
|
||||
bool is_empty(string key);
|
||||
|
||||
/**
|
||||
* 判断数据项是否是float数值类型
|
||||
* @param: [string key] 索引名称
|
||||
*/
|
||||
bool is_float_number(string key);
|
||||
|
||||
/**
|
||||
* 转换成键值对的字符串格式
|
||||
*/
|
||||
string to_str();
|
||||
|
||||
/**
|
||||
* 获取数据项的大小
|
||||
*/
|
||||
int size();
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
map<string, string> map_fields_;
|
||||
};
|
||||
|
||||
#endif
|
||||
71
src/common/Logger.cpp
Normal file
71
src/common/Logger.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "Logger.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <mutex>
|
||||
#include "Utils.h"
|
||||
//#include "common/spdlogger.h"
|
||||
|
||||
std::mutex g_mutex;
|
||||
|
||||
Logger::Logger(Logger::ELogType logtype, std::string filename, int line) : line_(line)
|
||||
{
|
||||
auto index = filename.find_last_of('\\');
|
||||
if (index != std::string::npos)
|
||||
{
|
||||
filename_ = filename.substr(index + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
filename_ = filename;
|
||||
}
|
||||
log_type_ = logtype;
|
||||
}
|
||||
|
||||
Logger::~Logger()
|
||||
{
|
||||
if (log_type_ == ELogType::E_LOG_OFF)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static std::string strLogType[int(ELogType::E_LOG_OFF)] = { "DEBUG", "INFO", "WARN", "ERROR" };
|
||||
|
||||
|
||||
// std::lock_guard<std::mutex> lock(g_mutex); // 虚构时自动解锁
|
||||
g_mutex.lock();
|
||||
//BACKGROUND代表背景,FOREGROUND代表前景
|
||||
//SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN);//设置黄色(红色+绿色)
|
||||
//SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
|
||||
std::string text = oss_.str();
|
||||
|
||||
if (log_type_ == ELogType::E_LOG_DEBUG)
|
||||
{
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);
|
||||
//Spdlogger::debug(text.c_str());
|
||||
}
|
||||
else if (log_type_ == ELogType::E_LOG_INFO)
|
||||
{
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE | FOREGROUND_GREEN);
|
||||
//Spdlogger::info(text.c_str());
|
||||
}
|
||||
else if (log_type_ == ELogType::E_LOG_WARN)
|
||||
{
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN);
|
||||
//Spdlogger::warn(text.c_str());
|
||||
}
|
||||
else if (log_type_ == ELogType::E_LOG_ERROR)
|
||||
{
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED);
|
||||
//Spdlogger::error(text.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
}
|
||||
|
||||
//std::cout << "[" << filename_ << ":" << line_ << "] [" << Utils::time_now_string_ms() << "][" << strLogType[int(log_type_)] << "] ";
|
||||
std::cout << "[" << Utils::timeNowStrMS() << "][" << strLogType[int(log_type_)] << "] ";
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
std::cout << "- " << text << std::endl << std::flush;
|
||||
g_mutex.unlock();
|
||||
}
|
||||
38
src/common/Logger.h
Normal file
38
src/common/Logger.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef _Logger_H_
|
||||
#define _Logger_H_
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
enum class ELogType
|
||||
{
|
||||
E_LOG_DEBUG = 0,
|
||||
E_LOG_INFO,
|
||||
E_LOG_WARN,
|
||||
E_LOG_ERROR,
|
||||
E_LOG_OFF
|
||||
};
|
||||
|
||||
public:
|
||||
Logger(Logger::ELogType logType, std::string filename, int line);
|
||||
~Logger();
|
||||
std::stringstream& Stream() { return oss_; }
|
||||
|
||||
private:
|
||||
std::stringstream oss_;
|
||||
ELogType log_type_;
|
||||
std::string filename_;
|
||||
int line_;
|
||||
};
|
||||
|
||||
#define XLOGD() Logger(Logger::ELogType::E_LOG_DEBUG, __FILE__, __LINE__).Stream()
|
||||
#define XLOGI() Logger(Logger::ELogType::E_LOG_INFO, __FILE__, __LINE__).Stream()
|
||||
#define XLOGW() Logger(Logger::ELogType::E_LOG_WARN, __FILE__, __LINE__).Stream()
|
||||
#define XLOGE() Logger(Logger::ELogType::E_LOG_ERROR, __FILE__, __LINE__).Stream()
|
||||
|
||||
#endif
|
||||
227
src/common/Snowflake.h
Normal file
227
src/common/Snowflake.h
Normal file
@@ -0,0 +1,227 @@
|
||||
#ifndef _JW_CORE_ID_WORKER_H_
|
||||
#define _JW_CORE_ID_WORKER_H_
|
||||
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <exception>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
// 如果不使用 mutex, 则开启下面这个定义, 但是我发现, 还是开启 mutex 功能, 速度比较快
|
||||
// #define SNOWFLAKE_ID_WORKER_NO_LOCK
|
||||
|
||||
|
||||
/**
|
||||
* @brief 分布式id生成类
|
||||
* https://segmentfault.com/a/1190000011282426
|
||||
* https://github.com/twitter/snowflake/blob/snowflake-2010/src/main/scala/com/twitter/service/snowflake/IdWorker.scala
|
||||
*
|
||||
* 64bit id: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
|
||||
* || || || | | |
|
||||
* |└---------------------------时间戳--------------------------┘└中心-┘└机器-┘ └----序列号----┘
|
||||
* |
|
||||
* 不用
|
||||
* SnowFlake的优点: 整体上按照时间自增排序, 并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分), 并且效率较高, 经测试, SnowFlake每秒能够产生26万ID左右.
|
||||
*/
|
||||
class Snowflake
|
||||
{
|
||||
public:
|
||||
static Snowflake& instance()
|
||||
{
|
||||
static Snowflake sf;
|
||||
return sf;
|
||||
}
|
||||
|
||||
typedef unsigned int UInt;
|
||||
typedef unsigned long long int UInt64;
|
||||
|
||||
#ifdef SNOWFLAKE_ID_WORKER_NO_LOCK
|
||||
typedef std::atomic<UInt> AtomicUInt;
|
||||
typedef std::atomic<UInt64> AtomicUInt64;
|
||||
#else
|
||||
typedef UInt AtomicUInt;
|
||||
typedef UInt64 AtomicUInt64;
|
||||
#endif
|
||||
|
||||
void set_worker_id(UInt workerId)
|
||||
{
|
||||
this->workerId = workerId;
|
||||
}
|
||||
|
||||
void set_datacenter_id(UInt datacenterId)
|
||||
{
|
||||
this->datacenterId = datacenterId;
|
||||
}
|
||||
|
||||
string nextIdStr()
|
||||
{
|
||||
return std::to_string(next_id());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得下一个ID (该方法是线程安全的)
|
||||
*
|
||||
* @return SnowflakeId
|
||||
*/
|
||||
UInt64 next_id()
|
||||
{
|
||||
#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK
|
||||
std::unique_lock<std::mutex> lock {mutex};
|
||||
AtomicUInt64 timestamp {0};
|
||||
#else
|
||||
static AtomicUInt64 timestamp {0};
|
||||
#endif
|
||||
timestamp = time_now_ms();
|
||||
|
||||
// 如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
|
||||
if (timestamp < lastTimestamp)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "clock moved backwards. Refusing to generate id for " << lastTimestamp - timestamp << " milliseconds";
|
||||
throw std::exception(std::runtime_error(s.str()));
|
||||
}
|
||||
|
||||
if (lastTimestamp == timestamp)
|
||||
{
|
||||
// 如果是同一时间生成的,则进行毫秒内序列
|
||||
sequence = (sequence + 1) & sequenceMask;
|
||||
if (0 == sequence)
|
||||
{
|
||||
// 毫秒内序列溢出, 阻塞到下一个毫秒,获得新的时间戳
|
||||
timestamp = next_millis(lastTimestamp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sequence = 0;
|
||||
}
|
||||
|
||||
#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK
|
||||
lastTimestamp = timestamp;
|
||||
#else
|
||||
lastTimestamp = timestamp.load();
|
||||
#endif
|
||||
|
||||
// 移位并通过或运算拼到一起组成64位的ID
|
||||
//return ((timestamp - twepoch) << timestampLeftShift)
|
||||
// | (datacenterId << datacenterIdShift)
|
||||
// | (workerId << workerIdShift)
|
||||
// | sequence;
|
||||
return ((timestamp - twepoch) << sequenceBits)
|
||||
//| (datacenterId << datacenterIdShift)
|
||||
//| (workerId << workerIdShift)
|
||||
| sequence;
|
||||
}
|
||||
|
||||
protected:
|
||||
Snowflake() : workerId(0), datacenterId(0), sequence(0), lastTimestamp(0)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回以毫秒为单位的当前时间
|
||||
*
|
||||
* @return 当前时间(毫秒)
|
||||
*/
|
||||
UInt64 time_now_ms() const
|
||||
{
|
||||
//auto t = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now());
|
||||
auto t = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
|
||||
return t.time_since_epoch().count();
|
||||
}
|
||||
|
||||
/**
|
||||
* 阻塞到下一个毫秒,直到获得新的时间戳
|
||||
*
|
||||
* @param lastTimestamp 上次生成ID的时间截
|
||||
* @return 当前时间戳
|
||||
*/
|
||||
UInt64 next_millis(UInt64 lastTimestamp) const
|
||||
{
|
||||
UInt64 timestamp = time_now_ms();
|
||||
while (timestamp <= lastTimestamp)
|
||||
{
|
||||
timestamp = time_now_ms();
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
#ifndef SNOWFLAKE_ID_WORKER_NO_LOCK
|
||||
std::mutex mutex;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 开始时间截 (2010-01-01 00:00:00.000) 1262275200000
|
||||
*/
|
||||
const UInt64 twepoch = 1262275200000;
|
||||
|
||||
/**
|
||||
* 机器id所占的位数
|
||||
*/
|
||||
const UInt workerIdBits = 5;
|
||||
|
||||
/**
|
||||
* 数据中心id所占的位数
|
||||
*/
|
||||
const UInt datacenterIdBits = 5;
|
||||
|
||||
/**
|
||||
* 序列所占的位数
|
||||
*/
|
||||
const UInt sequenceBits = 12;
|
||||
|
||||
/**
|
||||
* 机器ID向左移12位
|
||||
*/
|
||||
const UInt workerIdShift = sequenceBits;
|
||||
|
||||
/**
|
||||
* 数据标识id向左移17位
|
||||
*/
|
||||
const UInt datacenterIdShift = workerIdShift + workerIdBits;
|
||||
|
||||
/**
|
||||
* 时间截向左移22位
|
||||
*/
|
||||
const UInt timestampLeftShift = datacenterIdShift + datacenterIdBits;
|
||||
|
||||
/**
|
||||
* 支持的最大机器id,结果是31
|
||||
*/
|
||||
const UInt maxWorkerId = -1 ^ (-1 << workerIdBits);
|
||||
|
||||
/**
|
||||
* 支持的最大数据中心id,结果是31
|
||||
*/
|
||||
const UInt maxDatacenterId = -1 ^ (-1 << datacenterIdBits);
|
||||
|
||||
/**
|
||||
* 生成序列的掩码,这里为4095
|
||||
*/
|
||||
const UInt sequenceMask = -1 ^ (-1 << sequenceBits);
|
||||
|
||||
/**
|
||||
* 工作机器id(0~31)
|
||||
*/
|
||||
UInt workerId;
|
||||
|
||||
/**
|
||||
* 数据中心id(0~31)
|
||||
*/
|
||||
UInt datacenterId;
|
||||
|
||||
/**
|
||||
* 毫秒内序列(0~4095)
|
||||
*/
|
||||
AtomicUInt sequence {0};
|
||||
|
||||
/**
|
||||
* 上次生成ID的时间截
|
||||
*/
|
||||
AtomicUInt64 lastTimestamp {0};
|
||||
|
||||
};
|
||||
#endif // _JW_CORE_ID_WORKER_H_
|
||||
115
src/common/TimeUtils.cpp
Normal file
115
src/common/TimeUtils.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
#include "TimeUtils.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
|
||||
int64_t TimeUtils::now()
|
||||
{
|
||||
// return std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
return std::chrono::time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
}
|
||||
|
||||
|
||||
int64_t TimeUtils::now_ms()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
//return std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
}
|
||||
|
||||
std::string TimeUtils::now_datetime(char c1/* = '/'*/, char c2/* = ':'*/, char c3/* = ' '*/)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "%Y" << c1 << "%m" << c1 << "%d" << c3 << "%H" << c2 << "%M" << c2 << "%S";
|
||||
std::string fmt = ss.str();
|
||||
ss.str("");
|
||||
auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
ss << std::put_time(std::localtime(&t), fmt.c_str());
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string TimeUtils::now_date(char c1/* = '/'*/)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "%Y" << c1 << "%m" << c1 << "%d";
|
||||
std::string fmt = ss.str();
|
||||
ss.str("");
|
||||
auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
ss << std::put_time(std::localtime(&t), fmt.c_str());
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
int64_t TimeUtils::datetime2ts(std::string s)
|
||||
{
|
||||
// YYYY-mm-dd HH:MM:SS
|
||||
if (s.size() < 19) { return 0; }
|
||||
s[4] = s[7] = '-';
|
||||
s[10] = ' ';
|
||||
s[13] = s[16] = ':';
|
||||
std::tm t;
|
||||
std::stringstream ss(s);
|
||||
ss >> std::get_time(&t, "%Y-%m-%d %H:%M:%S");
|
||||
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&t));
|
||||
return std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch()).count();
|
||||
}
|
||||
int64_t TimeUtils::datetime2tms(std::string s)
|
||||
{
|
||||
if (s.size() < 19) { return 0; }
|
||||
s[4] = s[7] = '-';
|
||||
s[10] = ' ';
|
||||
s[13] = s[16] = ':';
|
||||
std::tm t;
|
||||
std::stringstream ss(s);
|
||||
ss >> std::get_time(&t, "%Y-%m-%d %H:%M:%S");
|
||||
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&t));
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch()).count();
|
||||
}
|
||||
|
||||
std::string TimeUtils::ts2datetime(int64_t ts, std::string fmt /*= "%Y-%m-%d %H:%M:%S"*/)
|
||||
{
|
||||
// std::localtime : 本地时区的时间
|
||||
// std::gmtime : 格林威治时间
|
||||
time_t t(ts);
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(std::localtime(&t), fmt.c_str());
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string TimeUtils::ts2date(int64_t ts)
|
||||
{
|
||||
time_t t(ts);
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(std::localtime(&t), "%Y-%m-%d");
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string TimeUtils::duration_str(int64_t t)
|
||||
{
|
||||
auto h = t / 3600;
|
||||
auto m = (t % 3600) / 60;
|
||||
auto s = (t % 3600) % 60;
|
||||
std::string str = std::to_string(s) + "秒";
|
||||
if (m > 0 || h > 0)
|
||||
{
|
||||
str = std::to_string(m) + "分" + str;
|
||||
}
|
||||
if (h > 0)
|
||||
{
|
||||
str = std::to_string(h) + "小时" + str;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
int64_t TimeUtils::tick(std::function<void()> func)
|
||||
{
|
||||
if (!func)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
func();
|
||||
auto end = std::chrono::steady_clock::now();
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
|
||||
}
|
||||
28
src/common/TimeUtils.h
Normal file
28
src/common/TimeUtils.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef _TimeUtils_H_
|
||||
#define _TimeUtils_H_
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
|
||||
class TimeUtils
|
||||
{
|
||||
public:
|
||||
static int64_t now();
|
||||
static int64_t now_ms();
|
||||
|
||||
static std::string now_datetime(char c1 = '-', char c2 = ':', char c3 = ' ');
|
||||
static std::string now_date(char c1 = '-');
|
||||
|
||||
static int64_t datetime2ts(std::string s);
|
||||
static int64_t datetime2tms(std::string s);
|
||||
static std::string ts2datetime(int64_t ts, std::string fmt = "%Y-%m-%d %H:%M:%S");
|
||||
static std::string ts2date(int64_t ts);
|
||||
|
||||
static std::string duration_str(int64_t t);
|
||||
|
||||
static int64_t tick(std::function<void()> func);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // !_TimeUtils_H_
|
||||
429
src/common/Utils.cpp
Normal file
429
src/common/Utils.cpp
Normal file
@@ -0,0 +1,429 @@
|
||||
#include "Utils.h"
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
string Utils::toStr(int v)
|
||||
{
|
||||
return std::to_string(v);
|
||||
}
|
||||
|
||||
string Utils::toStr(float v, int precision)
|
||||
{
|
||||
stringstream ss;
|
||||
ss.precision(precision);
|
||||
ss.setf(std::ios::fixed);
|
||||
ss << v;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
string Utils::toStr(double v, int precision)
|
||||
{
|
||||
stringstream ss;
|
||||
ss.precision(precision);
|
||||
ss.setf(std::ios::fixed);
|
||||
ss << v;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
int Utils::toInt(const std::string& str)
|
||||
{
|
||||
stringstream ss(str);
|
||||
int ret = 0;
|
||||
ss >> ret;
|
||||
return ret;
|
||||
}
|
||||
float Utils::toFloat(const string& str)
|
||||
{
|
||||
stringstream ss(str);
|
||||
float ret = 0.0f;
|
||||
ss >> ret;
|
||||
return ret;
|
||||
}
|
||||
double Utils::toDouble(const std::string& str)
|
||||
{
|
||||
stringstream ss(str);
|
||||
double ret = 0.0;
|
||||
ss >> ret;
|
||||
return ret;
|
||||
}
|
||||
int64_t Utils::hexbinToInt(const string& str, bool swap/*=false*/)
|
||||
{
|
||||
int64_t v = 0;
|
||||
for (size_t i = 0; i < str.size(); i++)
|
||||
{
|
||||
if (swap)
|
||||
{
|
||||
v = v + (str[str.size() - 1 - i] << (str.size() - 1 - i) * 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
v = v + (str[i] << (str.size() - 1 - i) * 8);
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
int Utils::hexstrToInt(const std::string& str)
|
||||
{
|
||||
stringstream ss;
|
||||
int ret;
|
||||
ss << hex << str.c_str();
|
||||
ss >> ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#include <iostream>
|
||||
string Utils::from_hex_text(string s)
|
||||
{
|
||||
vector<unsigned char> result;
|
||||
string tmp;
|
||||
stringstream ss;
|
||||
int v;
|
||||
for (auto ch : s)
|
||||
{
|
||||
if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'))
|
||||
{
|
||||
tmp += ch;
|
||||
if (tmp.size() == 2)
|
||||
{
|
||||
ss.clear();
|
||||
ss.str("");
|
||||
ss << hex << tmp;
|
||||
ss >> v;
|
||||
result.emplace_back((unsigned char)v);
|
||||
tmp.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
return string(result.begin(), result.end());
|
||||
}
|
||||
|
||||
//string Utils::fromHexText1(string s)
|
||||
//{
|
||||
// vector<unsigned char> result;
|
||||
// string tmp = s;
|
||||
// stringstream ss;
|
||||
// int v;
|
||||
// size_t pos = 0;
|
||||
// while (!tmp.empty())
|
||||
// {
|
||||
// if (pos >= tmp.size()) {
|
||||
// ss.clear();
|
||||
// ss.str("");
|
||||
// ss << hex << tmp;
|
||||
// ss >> v;
|
||||
// result.emplace_back((unsigned char)v);
|
||||
// tmp = "";
|
||||
// break;
|
||||
// }
|
||||
// auto& ch = tmp[pos];
|
||||
// bool flag = (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
|
||||
// if (!flag) {
|
||||
// ss.clear();
|
||||
// ss.str("");
|
||||
// ss << hex << tmp.substr(0, pos);
|
||||
// ss >> v;
|
||||
// tmp = tmp.substr(pos + 1);
|
||||
// result.emplace_back((unsigned char)v);
|
||||
// pos = 0;
|
||||
// }
|
||||
// ++pos;
|
||||
// }
|
||||
// return string(result.begin(), result.end());
|
||||
//}
|
||||
|
||||
string Utils::to_hex_text(string s, string d/* = " "*/)
|
||||
{
|
||||
stringstream ss;
|
||||
for (unsigned int i = 0; i < s.size(); ++i)
|
||||
{
|
||||
unsigned char ch = s[i];
|
||||
ss << std::setw(2) << std::setfill('0') << std::hex << std::uppercase << (int)ch << ((i < s.size() - 1) ? d : "");
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void time_point_to_duration()
|
||||
{
|
||||
auto tp = std::chrono::system_clock::now();
|
||||
|
||||
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch());
|
||||
cout << seconds.count() << " s" << endl;//seconds from 1970
|
||||
|
||||
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
|
||||
cout << ms.count() << " ms" << endl;
|
||||
|
||||
auto us = std::chrono::duration_cast<std::chrono::microseconds>(tp.time_since_epoch());
|
||||
cout << us.count() << " us" << endl;
|
||||
|
||||
auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(tp.time_since_epoch());
|
||||
cout << ns.count() << " ns" << endl;
|
||||
|
||||
cout << tp.time_since_epoch().count() << " default is ns" << endl;
|
||||
}
|
||||
|
||||
void duration_to_time_point()
|
||||
{
|
||||
std::uint64_t ticker = 1609756793160376465;
|
||||
auto ns = std::chrono::nanoseconds(ticker);
|
||||
|
||||
auto tp1 = std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds>(ns);
|
||||
auto tp2 = tp1 - std::chrono::hours(1);//time point before one hour
|
||||
cout << "tp1=" << tp1.time_since_epoch().count() << endl << "tp2=" << tp2.time_since_epoch().count() << endl;
|
||||
}
|
||||
|
||||
void format_time_point()
|
||||
{
|
||||
auto tp = std::chrono::system_clock::now();
|
||||
auto time = std::chrono::system_clock::to_time_t(tp);
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(std::localtime(&time), "%Y-%m-%d %H:%M:%S");
|
||||
|
||||
cout << ss.str() << endl;
|
||||
}
|
||||
|
||||
void parse_from_string()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "2021-01-06 18:47:35";
|
||||
|
||||
std::tm tm{};
|
||||
ss >> std::get_time(&tm, "%Y-%m-%d %H:%M:%S");
|
||||
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));
|
||||
cout << tp.time_since_epoch().count() << endl;
|
||||
}
|
||||
|
||||
int64_t Utils::timeNow()
|
||||
{
|
||||
// return std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
return std::chrono::time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
}
|
||||
int64_t Utils::timeNowMS()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
//return std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
}
|
||||
string Utils::timeNowStr(std::string fmt /*= "%Y-%m-%dT%H:%M:%S"*/)
|
||||
{
|
||||
auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(std::localtime(&t), fmt.c_str());
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
string Utils::timeNowStrMS(std::string fmt /*= "%Y-%m-%dT%H:%M:%S"*/)
|
||||
{
|
||||
auto tpNow = std::chrono::system_clock::now();
|
||||
auto time = std::chrono::system_clock::to_time_t(tpNow);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(std::localtime(&time), fmt.c_str());
|
||||
|
||||
auto tms = std::chrono::duration_cast<std::chrono::milliseconds>(tpNow.time_since_epoch());
|
||||
auto tseconds = std::chrono::duration_cast<std::chrono::seconds>(tpNow.time_since_epoch());
|
||||
ss << "." << std::setfill('0') << std::setw(3) << (tms - tseconds).count();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
string Utils::timeStr(int64_t ts, std::string fmt /*= "%Y-%m-%d %H:%M:%S"*/)
|
||||
{
|
||||
// std::localtime : 本地时区的时间
|
||||
// std::gmtime : 格林威治时间
|
||||
time_t t(ts);
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(std::localtime(&t), fmt.c_str());
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
string Utils::time_to_string(int64_t dt, std::string fmt /*= "%Y-%m-%d %H:%M:%S"*/)
|
||||
{
|
||||
auto ms = std::chrono::milliseconds(dt);
|
||||
auto tp = std::chrono::time_point<std::chrono::system_clock>(ms);
|
||||
time_t t = std::chrono::system_clock::to_time_t(tp);
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(std::localtime(&t), fmt.c_str());
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
// 2023-12-12 12:12:12
|
||||
int64_t Utils::time(string dt, int zone)
|
||||
{
|
||||
if (dt.empty())
|
||||
{
|
||||
return std::chrono::time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
}
|
||||
else
|
||||
{
|
||||
static string FMT_D = "yyyy-MM-dd";
|
||||
static string FMT_DT = "yyyy-MM-dd HH:mm:ss";
|
||||
static string FMT_DS = "yyyy-MM-dd HH:mm:ss.SSS";
|
||||
string fmt;
|
||||
if (dt.size() == FMT_D.size())
|
||||
{
|
||||
fmt = "%Y-%m-%d";
|
||||
dt[4] = dt[7] = '-';
|
||||
}
|
||||
else if (dt.size() == FMT_DT.size())
|
||||
{
|
||||
fmt = "%Y-%m-%d %H:%M:%S";
|
||||
dt[4] = dt[7] = '-';
|
||||
dt[10] = ' ';
|
||||
dt[13] = dt[16] = ':';
|
||||
}
|
||||
else if (dt.size() == FMT_DT.size())
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
stringstream ss(dt);
|
||||
|
||||
std::tm t {};
|
||||
ss >> std::get_time(&t, fmt.c_str());
|
||||
t.tm_hour += zone;
|
||||
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&t));
|
||||
return std::chrono::duration_cast<std::chrono::seconds>(tp.time_since_epoch()).count();
|
||||
//return std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch()).count();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Utils::time_string_to_tm(string dt, std::tm& t)
|
||||
{
|
||||
t.tm_year = 1900;
|
||||
t.tm_mon = 1;
|
||||
t.tm_mday = 1;
|
||||
static string FORMAT_D = "yyyy-mm-dd";
|
||||
static string FORMAT_DT = "yyyy-mm-dd HH:MM:SS";
|
||||
string fmt;
|
||||
if (dt.size() == FORMAT_D.size())
|
||||
{
|
||||
fmt = "%Y-%m-%d";
|
||||
dt[4] = dt[7] = '-';
|
||||
}
|
||||
else if (dt.size() >= FORMAT_DT.size())
|
||||
{
|
||||
fmt = "%Y-%m-%d %H:%M:%S";
|
||||
dt[4] = dt[7] = '-';
|
||||
dt[10] = ' ';
|
||||
dt[13] = dt[16] = ':';
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
stringstream ss;
|
||||
ss << dt;
|
||||
ss >> std::get_time(&t, fmt.c_str());
|
||||
t.tm_year += 1900;
|
||||
t.tm_mon += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Utils::sleep_ms(int ms)
|
||||
{
|
||||
// 计算时间间隔:
|
||||
//auto start = std::chrono::high_resolution_clock::now();
|
||||
//auto end = std::chrono::high_resolution_clock::now();
|
||||
//std::chrono::duration<double, std::milli> elapsed = end - start;
|
||||
//int64_t t = elapsed.count();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
|
||||
}
|
||||
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
unsigned short Utils::crc16(unsigned char* data, unsigned int len)
|
||||
{
|
||||
if (data == NULL || len == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
unsigned short crc = 0xffff;
|
||||
unsigned short FACTOR = 0xa001;
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
crc ^= data[i];
|
||||
for (int j = 0; j < 8; j++)
|
||||
{
|
||||
if ((crc & 0x0001) != 0)
|
||||
{
|
||||
crc >>= 1;
|
||||
crc ^= FACTOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
//(unsigned char)(CRC & 0x00ff);
|
||||
//(unsigned char)(CRC >> 8);
|
||||
return crc;
|
||||
}
|
||||
|
||||
string Utils::gbkToUtf8(string s)
|
||||
{
|
||||
int n = MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, NULL, 0);
|
||||
WCHAR* str1 = new WCHAR[n];
|
||||
MultiByteToWideChar(CP_ACP, 0, s.c_str(), -1, str1, n);
|
||||
n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
|
||||
vector<char> s_utf8(n, 0);
|
||||
WideCharToMultiByte(CP_UTF8, 0, str1, -1, &s_utf8[0], n, NULL, NULL);
|
||||
delete[]str1;
|
||||
str1 = NULL;
|
||||
return string(s_utf8.begin(), s_utf8.end());
|
||||
}
|
||||
|
||||
string Utils::utf8ToGbk(string s)
|
||||
{
|
||||
string s_gbk = "";
|
||||
int n = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
|
||||
WCHAR* str1 = new WCHAR[n];
|
||||
MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, str1, n);
|
||||
n = WideCharToMultiByte(CP_ACP, 0, str1, -1, NULL, 0, NULL, NULL);
|
||||
char* str2 = new char[n];
|
||||
WideCharToMultiByte(CP_ACP, 0, str1, -1, str2, n, NULL, NULL);
|
||||
s_gbk = str2;
|
||||
delete[] str1;
|
||||
str1 = NULL;
|
||||
delete[] str2;
|
||||
str2 = NULL;
|
||||
return s_gbk;
|
||||
}
|
||||
|
||||
#include <random>
|
||||
int Utils::random(int min, int max)
|
||||
{
|
||||
//生成 a 到 b 之间(包含)均匀分布的随机数
|
||||
uniform_int_distribution<unsigned> rand_u(min, max);
|
||||
static default_random_engine rand_e; // 生成无符号随机整数
|
||||
return rand_u(rand_e);
|
||||
}
|
||||
|
||||
void Utils::split(string buf, string c, vector<string>& res)
|
||||
{
|
||||
if (buf.size() == 0 || c.size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string tmp = buf;
|
||||
while (true)
|
||||
{
|
||||
auto pos = tmp.find(c);
|
||||
if (pos == string::npos)
|
||||
{
|
||||
res.push_back(tmp);
|
||||
break;
|
||||
}
|
||||
res.push_back((pos == 0) ? "" : tmp.substr(0, pos));
|
||||
tmp = tmp.substr(pos + c.size());
|
||||
}
|
||||
}
|
||||
111
src/common/Utils.h
Normal file
111
src/common/Utils.h
Normal file
@@ -0,0 +1,111 @@
|
||||
#ifndef _Utils_H_
|
||||
#define _Utils_H_
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
#include <iomanip>
|
||||
#include <functional>
|
||||
#include <thread>
|
||||
|
||||
//#include "Crypto.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Utils
|
||||
{
|
||||
public:
|
||||
static string toStr(int v);
|
||||
static string toStr(float v, int precision = 2);
|
||||
static string toStr(double v, int precision = 2);
|
||||
|
||||
static int toInt(const std::string& str);
|
||||
static float toFloat(const string& str);
|
||||
static double toDouble(const string& str);
|
||||
|
||||
static int64_t hexbinToInt(const string& str, bool swap = false);
|
||||
|
||||
static int hexstrToInt(const string& str);
|
||||
|
||||
static string from_hex_text(string s);
|
||||
static string to_hex_text(string s, string d = " ");
|
||||
|
||||
template<typename T>
|
||||
static void append_bytes(vector<unsigned char>& dest, const T& src, int len)
|
||||
{
|
||||
int start = static_cast<int>(dest.size());
|
||||
dest.resize(start + len);
|
||||
memcpy_s(&dest[start], len, &src, len);
|
||||
}
|
||||
|
||||
static int64_t timeNow();
|
||||
static int64_t timeNowMS();
|
||||
static string timeNowStr(std::string fmt = "%Y-%m-%d %H:%M:%S");
|
||||
static string timeNowStrMS(std::string fmt = "%Y-%m-%d %H:%M:%S");
|
||||
static string timeStr(int64_t ts, std::string fmt = "%Y-%m-%d %H:%M:%S");
|
||||
|
||||
static int64_t time(string dt="", int zone = 0);
|
||||
|
||||
static string time_to_string(int64_t dt, std::string fmt="%Y-%m-%d %H:%M:%S");
|
||||
static bool time_string_to_tm(string dt, std::tm& t);
|
||||
|
||||
|
||||
|
||||
std::string duration_str(int64_t t)
|
||||
{
|
||||
auto h = t / 3600;
|
||||
auto m = (t % 3600) / 60;
|
||||
auto s = (t % 3600) % 60;
|
||||
std::string str = std::to_string(s) + "秒";
|
||||
if (m > 0 || h > 0)
|
||||
{
|
||||
str = std::to_string(m) + "分" + str;
|
||||
}
|
||||
if (h > 0)
|
||||
{
|
||||
str = std::to_string(h) + "小时" + str;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static unsigned short crc16(unsigned char* data, unsigned int len);
|
||||
|
||||
static string Utils::gbkToUtf8(string s);
|
||||
static string Utils::utf8ToGbk(string s);
|
||||
|
||||
static void sleep_ms(int ms);
|
||||
|
||||
static int random(int min, int max);
|
||||
|
||||
static void split(string buf, string c, vector<string>& res);
|
||||
};
|
||||
|
||||
class TimeTick
|
||||
{
|
||||
public:
|
||||
int64_t tickMS_ = 0;
|
||||
|
||||
TimeTick()
|
||||
{
|
||||
tickMS_ = Utils::timeNowMS();
|
||||
}
|
||||
|
||||
bool elapse(int64_t ms, bool reset = true)
|
||||
{
|
||||
auto tick_now = Utils::timeNowMS();
|
||||
bool res = tick_now - tickMS_ > ms;
|
||||
if (res && reset)
|
||||
{
|
||||
tickMS_ = tick_now;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
tickMS_ = Utils::timeNowMS();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !!! _Utils_H_
|
||||
76
src/database/0/DbSqlite.cpp
Normal file
76
src/database/0/DbSqlite.cpp
Normal 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
32
src/database/0/DbSqlite.h
Normal 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
218
src/database/DaoEntity.cpp
Normal 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
111
src/database/DaoEntity.h
Normal 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_
|
||||
122
src/database/MysqlClient.cpp
Normal file
122
src/database/MysqlClient.cpp
Normal 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;
|
||||
}
|
||||
68
src/database/MysqlClient.h
Normal file
68
src/database/MysqlClient.h
Normal 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
88
src/database/SQL.h
Normal 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;
|
||||
};
|
||||
120
src/database/dao/DaoAdmin.cpp
Normal file
120
src/database/dao/DaoAdmin.cpp
Normal 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
118
src/database/dao/DaoAdmin.h
Normal 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 分页信息
|
||||
* @param:result 查询结果数据集
|
||||
*/
|
||||
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);
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
81
src/database/dao/DaoBattery.cpp
Normal file
81
src/database/dao/DaoBattery.cpp
Normal 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);
|
||||
}
|
||||
57
src/database/dao/DaoBattery.h
Normal file
57
src/database/dao/DaoBattery.h
Normal 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);
|
||||
|
||||
};
|
||||
49
src/database/dao/DaoCar.cpp
Normal file
49
src/database/dao/DaoCar.cpp
Normal 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
41
src/database/dao/DaoCar.h
Normal 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);
|
||||
};
|
||||
48
src/database/dao/DaoCharge.cpp
Normal file
48
src/database/dao/DaoCharge.cpp
Normal 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);
|
||||
}
|
||||
86
src/database/dao/DaoCharge.h
Normal file
86
src/database/dao/DaoCharge.h
Normal 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_
|
||||
61
src/database/dao/DaoDevice.cpp
Normal file
61
src/database/dao/DaoDevice.cpp
Normal 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);
|
||||
}
|
||||
101
src/database/dao/DaoDevice.h
Normal file
101
src/database/dao/DaoDevice.h
Normal 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_
|
||||
84
src/database/dao/DaoStat.cpp
Normal file
84
src/database/dao/DaoStat.cpp
Normal 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);
|
||||
}
|
||||
69
src/database/dao/DaoStat.h
Normal file
69
src/database/dao/DaoStat.h
Normal 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);
|
||||
|
||||
};
|
||||
63
src/database/dao/DaoSwap.cpp
Normal file
63
src/database/dao/DaoSwap.cpp
Normal 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 error:bizid 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;
|
||||
}
|
||||
56
src/database/dao/DaoSwap.h
Normal file
56
src/database/dao/DaoSwap.h
Normal 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
239
src/database/dao/DaoSys.cpp
Normal 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
192
src/database/dao/DaoSys.h
Normal 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 '报文类型, 1:发送,2:接收',
|
||||
`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);
|
||||
};
|
||||
45
src/database/dao/DaoUser.cpp
Normal file
45
src/database/dao/DaoUser.cpp
Normal 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);
|
||||
}
|
||||
68
src/database/dao/DaoUser.h
Normal file
68
src/database/dao/DaoUser.h
Normal 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);
|
||||
};
|
||||
62
src/main.cpp
Normal file
62
src/main.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <Windows.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QtWebEngineWidgets/QtWebEngineWidgets>
|
||||
#include <filesystem>
|
||||
|
||||
#include "widgets/MainWindow.h"
|
||||
#include "common/Utils.h"
|
||||
#include "app/Application.h"
|
||||
#include "app/Dao.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
SetConsoleOutputCP(CP_UTF8); // 设置控制台输出为UTF-8
|
||||
|
||||
auto& mysqlOptions = DaoEntity::mysqlOptions();
|
||||
mysqlOptions.host = "localhost";
|
||||
mysqlOptions.port = 3306;
|
||||
mysqlOptions.user = "root";
|
||||
mysqlOptions.password = "123456";
|
||||
mysqlOptions.dbname = "ees";
|
||||
|
||||
|
||||
std::string filename = "assets/html/data中文.txt";
|
||||
|
||||
std::filesystem::path filePath = std::filesystem::u8path("assets/html/data中文.txt");
|
||||
//std::locale::global(locale(""));//将全局区域设为操作系统默认区域
|
||||
std::ifstream ifs(filePath, std::ios::binary);
|
||||
//std::locale::global(locale("C"));//还原全局区域设定
|
||||
|
||||
if (ifs.is_open())
|
||||
{
|
||||
// 将文件指针移动到末尾获取文件大小
|
||||
ifs.seekg(0, std::ios::end);
|
||||
std::streamsize size = ifs.tellg();
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
|
||||
std::string buf(size, '\0');
|
||||
ifs.read(&buf[0], size);
|
||||
std::cout << "文件内容: " << buf << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "error" << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 运行后台服务
|
||||
Application::instance().init();
|
||||
|
||||
// 运行QT主窗口
|
||||
QApplication qapp(argc, argv);
|
||||
MainWindow mainWin;
|
||||
mainWin.setWindowTitle("风光储能站控制管理系统");
|
||||
mainWin.resize(1920, 1080);
|
||||
mainWin.show();
|
||||
qapp.exec();
|
||||
return 0;
|
||||
}
|
||||
184
src/widgets/MainWindow.cpp
Normal file
184
src/widgets/MainWindow.cpp
Normal file
@@ -0,0 +1,184 @@
|
||||
#include "MainWindow.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
static std::string DatetimeNow(char c1 = '-', char c2 = ':', char c3 = ' ')
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "%Y" << c1 << "%m" << c1 << "%d" << c3 << "%H" << c2 << "%M" << c2 << "%S";
|
||||
std::string fmt = ss.str();
|
||||
ss.str("");
|
||||
auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
|
||||
ss << std::put_time(std::localtime(&t), fmt.c_str());
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static const std::string STY_BTN_MENU =
|
||||
"QPushButton{background:rgba(50,128,218,200);color:white;border-radius:5px;border:2px solid rgb(10,120,215);font:bold 18px;}"
|
||||
"QPushButton:hover{background-color:rgb(32,164,128);}"
|
||||
"QPushButton:pressed{border-width:3px 0 0 3px;background-color:rgb(150,150,150);border-style:inset;}"
|
||||
"QPushButton:disabled{color:rgb(150,150,150);}";
|
||||
|
||||
static const std::string STY_BTN_MENU_ACTIVE =
|
||||
"QPushButton{background:rgba(32,164,128,200);color:white;border-radius:5px;border:2px solid rgb(10,255,215);font:bold 18px;}"
|
||||
"QPushButton:hover{background-color:rgb(32,164,128);}"
|
||||
"QPushButton:pressed{border-width:3px 0 0 3px;background-color:rgb(150,150,150);border-style:inset;}"
|
||||
"QPushButton:disabled{color:rgb(150,150,150);}";
|
||||
|
||||
|
||||
void Menu::init(
|
||||
QWidget* parent,
|
||||
int x, int y,
|
||||
std::vector<std::string>& vecMenuId,
|
||||
std::function<void(std::string id)> cb)
|
||||
{
|
||||
int num = vecMenuId.size();
|
||||
x = (1920 - (num*110 - 10))*0.5;
|
||||
|
||||
cb_ = cb;
|
||||
for (int i = 0; i<num; i++)
|
||||
{
|
||||
std::string menuName = vecMenuId[i];
|
||||
auto btn = std::make_shared<QPushButton>(parent);
|
||||
btn->setGeometry(x+i*110, y, 100, 35);
|
||||
btn->setText(menuName.c_str());
|
||||
btn->setFont(QFont("微软雅黑"));
|
||||
if (menuName == curMenuId_)
|
||||
{
|
||||
btn->setStyleSheet(STY_BTN_MENU_ACTIVE.c_str());
|
||||
activeBtn_ = btn.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
btn->setStyleSheet(STY_BTN_MENU.c_str());
|
||||
}
|
||||
vecBtn_.push_back(btn);
|
||||
QObject::connect(btn.get(), &QPushButton::clicked, this, &Menu::onMenuBtnClicked);
|
||||
}
|
||||
}
|
||||
void Menu::onMenuBtnClicked()
|
||||
{
|
||||
QPushButton* btn = qobject_cast<QPushButton*>(sender());
|
||||
std::string menuName = btn->text().toStdString();
|
||||
|
||||
if (menuName == curMenuId_)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
curMenuId_ = menuName;
|
||||
if (activeBtn_) { activeBtn_->setStyleSheet(STY_BTN_MENU.c_str()); }
|
||||
activeBtn_ = btn;
|
||||
activeBtn_->setStyleSheet(STY_BTN_MENU_ACTIVE.c_str());
|
||||
|
||||
if (cb_) { cb_(curMenuId_); }
|
||||
}
|
||||
|
||||
#include "WebHandler.h"
|
||||
#include <QWebChannel>
|
||||
|
||||
MainWindow::MainWindow()
|
||||
{
|
||||
webView = std::make_shared<QWebEngineView>(this);
|
||||
|
||||
MyWebHandler* myWebHandler = new MyWebHandler();
|
||||
QWebChannel* webChannel = new QWebChannel();
|
||||
webChannel->registerObject("cppNative", myWebHandler);
|
||||
webView->page()->setWebChannel(webChannel);
|
||||
|
||||
webView->setGeometry(0, 0, 1920, 1080);
|
||||
// 默认设置透明, 解决加载时的白屏闪烁
|
||||
webView->page()->setBackgroundColor(Qt::transparent);
|
||||
|
||||
webView->setContextMenuPolicy(Qt::NoContextMenu);
|
||||
//webView.load(QUrl("https://www.baidu.com"));
|
||||
webView->load(QUrl("file:///assets/html/main.html"));
|
||||
//connect(wWebView.get(), &QWebEngineView::loadFinished, this, &MyWidget::slotLoadFinished);
|
||||
|
||||
//std::string htmlContent = "HelloWorld";
|
||||
//webView->setHtml(htmlContent.c_str(), QUrl("file:///assets/html/"));
|
||||
webView->show();
|
||||
return;
|
||||
|
||||
QUI::label(labBkg_, this, 0, 0, 1920, 1080, "");
|
||||
labBkg_.setPixmap(QPixmap("assets/ui/bkg01.png"));
|
||||
|
||||
// 顶部区域: 显示系统信息、时间、登录用户信息
|
||||
//QUI::label(labBkgHead_, this, 0, 0, 1920, 114, "");
|
||||
//labBkgHead_.setPixmap(QPixmap("assets/ui/bkg_head.png"));
|
||||
|
||||
// 系统名称
|
||||
QUI::label(labTitle_, this, 100, 20, 520, 50, "", "font:bold 42px;color:white;");
|
||||
// 时钟标签
|
||||
QUI::label(labTime_, this, 50, 25, 320, 40, DatetimeNow().c_str(), "");
|
||||
labTime_.setFont(QFont("微软雅黑", 16, 1000));
|
||||
|
||||
//wPage_ = std::make_shared<WidgetPageHome>(this);
|
||||
//wPage_->setGeometry(0, 115, 1920, 1080-115);
|
||||
//wPage_->show();
|
||||
|
||||
this->initMenu();
|
||||
|
||||
// 登录框
|
||||
wLogin_.setParent(this);
|
||||
wLogin_.show();
|
||||
|
||||
connect(&wLogin_, &WidgetLogin::signalLoginSuccess, this, &MainWindow::slotLoginSuccess);
|
||||
|
||||
QObject::connect(&timer_, &QTimer::timeout, this, &MainWindow::onTimeout);
|
||||
timer_.start(1000);
|
||||
}
|
||||
|
||||
void MainWindow::initMenu()
|
||||
{
|
||||
std::vector<std::string> vecMenuId =
|
||||
{
|
||||
"系统总览", "运行监控", "预测监控", "统计分析", "安全管理", "系统管理", "服务管理", "参数管理"
|
||||
};
|
||||
|
||||
menu_ = std::make_shared<Menu>();
|
||||
menu_->init(this, 740, 1030, vecMenuId, [=](std::string menuId) { this->onMenuClicked(menuId); });
|
||||
|
||||
// 考虑处理二级菜单
|
||||
}
|
||||
|
||||
void MainWindow::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
auto& size = event->size();
|
||||
if (webView)
|
||||
{
|
||||
webView->resize(size);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::slotLoginSuccess()
|
||||
{
|
||||
wLogin_.hide();
|
||||
onMenuClicked("系统总览");
|
||||
}
|
||||
|
||||
void MainWindow::onMenuClicked(std::string menuId)
|
||||
{
|
||||
auto w = WidgetPage::create(this, menuId);
|
||||
if (w)
|
||||
{
|
||||
w->setGeometry(0, 90, 1920, 950);
|
||||
wPage_ = w;
|
||||
wPage_->show();
|
||||
//wPage_->updateData();
|
||||
}
|
||||
else
|
||||
{
|
||||
wPage_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onTimeout()
|
||||
{
|
||||
if (wPage_)
|
||||
{
|
||||
//wPage_->updateData();
|
||||
}
|
||||
labTime_.setText(DatetimeNow().c_str());
|
||||
}
|
||||
55
src/widgets/MainWindow.h
Normal file
55
src/widgets/MainWindow.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#include <QMainWindow>
|
||||
#include <QtWebEngineWidgets/QWebEngineView>
|
||||
#include <vector>
|
||||
#include <QTimer>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
||||
#include "uihelper.h"
|
||||
#include "WidgetLogin.h"
|
||||
#include "WidgetPage.h"
|
||||
|
||||
class Menu : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
std::string curMenuId_;
|
||||
std::vector<std::shared_ptr<QPushButton>> vecBtn_;
|
||||
QPushButton* activeBtn_ = NULL;
|
||||
std::function<void(std::string id)> cb_ = nullptr;
|
||||
|
||||
void init(QWidget* parent, int x, int y, std::vector<std::string>& vecMenuId, std::function<void(std::string id)> cb);
|
||||
void onMenuBtnClicked();
|
||||
};
|
||||
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainWindow();
|
||||
void initMenu();
|
||||
|
||||
void resizeEvent(QResizeEvent* event);
|
||||
|
||||
public slots:
|
||||
void slotLoginSuccess();
|
||||
void onMenuClicked(std::string menuId);
|
||||
void onTimeout();
|
||||
|
||||
public:
|
||||
QLabel labBkg_;
|
||||
QLabel labBkgHead_;
|
||||
QLabel labTitle_;
|
||||
QLabel labTime_;
|
||||
|
||||
WidgetLogin wLogin_;
|
||||
|
||||
QTimer timer_;
|
||||
|
||||
std::shared_ptr<WidgetPage> wPage_ = nullptr;
|
||||
|
||||
std::shared_ptr<Menu> menu_ = nullptr;
|
||||
|
||||
std::shared_ptr<QWebEngineView> webView;
|
||||
};
|
||||
604
src/widgets/WebHandler.cpp
Normal file
604
src/widgets/WebHandler.cpp
Normal file
@@ -0,0 +1,604 @@
|
||||
#include "WebHandler.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include "common/Utils.h"
|
||||
#include "common/Logger.h"
|
||||
#include "Snowflake.h"
|
||||
#include "app/Dao.h"
|
||||
|
||||
static void JSsetResPaginaion(QVariantMap& result, std::vector<DataFields>& data, int page, int pageSize, int count, int code, string err)
|
||||
{
|
||||
result["code"] = code;
|
||||
result["err"] = "操作成功";
|
||||
result["count"] = count;
|
||||
result["page"] = page;
|
||||
result["pageSize"] = pageSize;
|
||||
|
||||
QVariantList listRow;
|
||||
for (auto& fields: data)
|
||||
{
|
||||
QVariantMap row;
|
||||
for (auto& field: fields.fields())
|
||||
{
|
||||
row[field.first.c_str()] = field.second.c_str();
|
||||
}
|
||||
listRow << row;
|
||||
}
|
||||
result["data"] = listRow;
|
||||
}
|
||||
|
||||
static void JSgetReqParam(QString key, QVariantMap& params, DataFields& fields)
|
||||
{
|
||||
if (params.contains(key)) fields.set(key.toStdString(), params[key].toString().toStdString());
|
||||
}
|
||||
|
||||
void MyWebHandler::setNativeText(const QString& text)
|
||||
{
|
||||
nativeText_ = text;
|
||||
emit signalNativeTextChanged(text);
|
||||
}
|
||||
|
||||
void MyWebHandler::log(const QString& text)
|
||||
{
|
||||
XLOGD() << "[JS] " << text.toStdString();
|
||||
}
|
||||
|
||||
QString MyWebHandler::readFile(const QString& filename)
|
||||
{
|
||||
//std::string filePath = "assets/html/系统管理/index.html"; //filename.toStdString();
|
||||
std::filesystem::path filePath = std::filesystem::u8path(filename.toStdString());
|
||||
XLOGD() << "[cppNative] readFile: " << filePath;
|
||||
std::ifstream ifs(filePath);
|
||||
if (ifs.is_open())
|
||||
{
|
||||
// 获取文件大小
|
||||
ifs.seekg(0, std::ios::end);
|
||||
std::streamsize size = ifs.tellg();
|
||||
XLOGD() << "[cppNative] readFile [" << filePath << "] success, data size=" << size;
|
||||
|
||||
// 定位回文件开始,读取文件内容到缓冲区
|
||||
ifs.seekg(0, std::ios::beg);
|
||||
std::string buf(size, '\0');
|
||||
ifs.read(&buf[0], size);
|
||||
ifs.close();
|
||||
return buf.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
XLOGD() << "[cppNative] readFile [" << filePath << "] failed.";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
QVariantMap MyWebHandler::queryUserList(int page, int pageSize)
|
||||
{
|
||||
XLOGD() << "[cppNative] queryUserList";
|
||||
std::vector<DataFields> res;
|
||||
DAO::queryUser(res);
|
||||
|
||||
QVariantMap result;
|
||||
JSsetResPaginaion(result, res, page, pageSize, res.size(), 0, "操作成功");
|
||||
return result;
|
||||
}
|
||||
|
||||
int MyWebHandler::insertUser(QVariantMap params)
|
||||
{
|
||||
DataFields fields;
|
||||
JSgetReqParam("account", params, fields);
|
||||
fields.set("passwd", "123456");
|
||||
JSgetReqParam("name", params, fields);
|
||||
JSgetReqParam("gender", params, fields);
|
||||
JSgetReqParam("age", params, fields);
|
||||
JSgetReqParam("phone", params, fields);
|
||||
JSgetReqParam("email", params, fields);
|
||||
JSgetReqParam("is_open", params, fields);
|
||||
XLOGD() << "[cppNative] insertUser: params=" << fields.to_str();
|
||||
|
||||
bool ret = DAO::insertUser(fields);
|
||||
|
||||
|
||||
|
||||
// 设置用户角色
|
||||
std::string user_id = fields.get_str("user_id");
|
||||
if (params.contains("role_id")) {
|
||||
|
||||
int role_id = params["role_id"].toInt();
|
||||
DataFields fieldsUserRole;
|
||||
fieldsUserRole.set("user_id", user_id);
|
||||
fieldsUserRole.set("role_id", role_id);
|
||||
fieldsUserRole.set("create_time", Utils::timeNowStr());
|
||||
auto dao = DAO::get("user_role");
|
||||
ret = dao->insertFields(fieldsUserRole);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int MyWebHandler::deleteUser(const QString& userId) { return 1; }
|
||||
|
||||
int MyWebHandler::updateUser(const QString& userId, QVariantMap params)
|
||||
{
|
||||
XLOGD() << "[cppNative] updateUser";
|
||||
|
||||
int ret = 1;
|
||||
DataFields fields;
|
||||
|
||||
JSgetReqParam("account", params, fields);
|
||||
JSgetReqParam("name", params, fields);
|
||||
JSgetReqParam("gender", params, fields);
|
||||
JSgetReqParam("age", params, fields);
|
||||
JSgetReqParam("phone", params, fields);
|
||||
JSgetReqParam("email", params, fields);
|
||||
JSgetReqParam("is_open", params, fields);
|
||||
if (params.size() > 0)
|
||||
{
|
||||
ret = DAO::updateUserById(userId.toStdString(), fields);
|
||||
XLOGD() << "updateUser: ret=" << ret;
|
||||
}
|
||||
|
||||
if (params.contains("role_id")) {
|
||||
int role_id = params["role_id"].toInt();
|
||||
fields.clear();
|
||||
fields.set("user_id", userId.toStdString());
|
||||
fields.set("role_id", role_id);
|
||||
fields.set("create_time", Utils::timeNowStr());
|
||||
fields.set("update_time", Utils::timeNowStr());
|
||||
//fields.set("update_by", "");
|
||||
|
||||
auto dao = DAO::get("user_role");
|
||||
std::vector<std::string> keysUpdate = {"role_id", "update_time"};
|
||||
bool res = dao->duplicateUpdate(fields, keysUpdate);
|
||||
ret = ret ? 0 : 1;
|
||||
XLOGD() << "updateUser, update role, ret=" << ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// ================================================================================================================
|
||||
// 角色管理接口
|
||||
QVariantMap MyWebHandler::queryRoleList(int page, int pageSize)
|
||||
{
|
||||
std::vector<DataFields> res;
|
||||
auto dao = DAO::get("role");
|
||||
bool ret = dao->exec("SELECT * FROM role;", res);
|
||||
|
||||
QVariantMap result;
|
||||
JSsetResPaginaion(result, res, page, pageSize, res.size(), 0, "操作成功");
|
||||
|
||||
XLOGD() << "[cppNative] queryRoleList " << (ret ? "success." : "failed.");
|
||||
return result;
|
||||
}
|
||||
int MyWebHandler::insertRole(QVariantMap params)
|
||||
{
|
||||
DataFields fields;
|
||||
if (params.contains("name")) fields.set("name", params["name"].toString().toStdString());
|
||||
if (fields.size() == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (params.contains("describe")) fields.set("describe", params["describe"].toString().toStdString());
|
||||
|
||||
// 数据表 role_id 是自增id
|
||||
fields.set("create_time", Utils::timeNowStr());
|
||||
fields.set("update_time", Utils::timeNowStr());
|
||||
auto dao = DAO::get("role");
|
||||
bool ret = dao->insertFields(fields);
|
||||
return ret ? 0: 1;
|
||||
}
|
||||
int MyWebHandler::deleteRole(const QString& roleId) { return 1; }
|
||||
int MyWebHandler::updateRole(const QString& roleId, QVariantMap params)
|
||||
{
|
||||
DataFields fields;
|
||||
JSgetReqParam("name", params, fields);
|
||||
JSgetReqParam("describe", params, fields);
|
||||
if (fields.size() <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fields.set("update_time", Utils::timeNowStr());
|
||||
|
||||
std::string sqlC = " WHERE role_id='" + roleId.toStdString() + "'";
|
||||
auto dao = DAO::get("role");
|
||||
bool ret = dao->updateFields(fields, sqlC);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
|
||||
QVariantList MyWebHandler::queryRolePermissionList(int roleId)
|
||||
{
|
||||
std::vector<DataFields> result;
|
||||
std::string sql = "SELECT p.permission_id, p.name, rp.role_id, rp.is_open FROM permission p "
|
||||
"LEFT JOIN role_permission rp ON(rp.permission_id = p.permission_id AND rp.role_id = '" + std::to_string(roleId) +"') WHERE p.is_open='1';";
|
||||
|
||||
auto dao = DAO::get("role_permission");
|
||||
bool ret = dao->exec(sql, result);
|
||||
|
||||
QVariantList listRow;
|
||||
for (auto& fields: result)
|
||||
{
|
||||
QVariantMap row;
|
||||
for (auto& field: fields.fields())
|
||||
{
|
||||
row[field.first.c_str()] = field.second.c_str();
|
||||
}
|
||||
listRow << row;
|
||||
}
|
||||
return listRow;
|
||||
};
|
||||
int MyWebHandler::updateRolePermission(int roleId, QVariantList params)
|
||||
{
|
||||
auto dao = DAO::get("role_permission");
|
||||
|
||||
std::string sql = "DELETE FROM role_permission WHERE role_id='" + std::to_string(roleId) + "';";
|
||||
bool ret = dao->exec(sql);
|
||||
|
||||
std::vector<DataFields> vecFields;
|
||||
for (QVariant& item: params)
|
||||
{
|
||||
if (item.canConvert<QVariantMap>())
|
||||
{
|
||||
QVariantMap itemMap = item.toMap();
|
||||
DataFields fields;
|
||||
fields.set("role_id", roleId);
|
||||
JSgetReqParam("permission_id", itemMap, fields);
|
||||
JSgetReqParam("is_open", itemMap, fields);
|
||||
vecFields.push_back(fields);
|
||||
}
|
||||
}
|
||||
ret = dao->insertFields(vecFields);
|
||||
return ret ? 0 : 1;
|
||||
};
|
||||
|
||||
// ================================================================================================================
|
||||
// 权限管理接口
|
||||
QVariantMap MyWebHandler::queryPermissionList(int page, int pageSize)
|
||||
{
|
||||
std::vector<DataFields> res;
|
||||
auto dao = DAO::get("permission");
|
||||
bool ret = dao->exec("SELECT * FROM permission;", res);
|
||||
|
||||
QVariantMap result;
|
||||
JSsetResPaginaion(result, res, page, pageSize, res.size(), 0, "操作成功");
|
||||
return result;
|
||||
}
|
||||
|
||||
int MyWebHandler::insertPermission(QVariantMap params)
|
||||
{
|
||||
DataFields fields;
|
||||
JSgetReqParam("name", params, fields);
|
||||
JSgetReqParam("describe", params, fields);
|
||||
JSgetReqParam("is_open", params, fields);
|
||||
fields.set("create_time", Utils::timeNowStr());
|
||||
fields.set("update_time", Utils::timeNowStr());
|
||||
|
||||
auto dao = DAO::get("permission");
|
||||
bool ret = dao->insertFields(fields);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
|
||||
int MyWebHandler::deletePermission(const QString& permissionId) { return 1; }
|
||||
int MyWebHandler::updatePermission(const QString& permissionId, QVariantMap params)
|
||||
{
|
||||
DataFields fields;
|
||||
JSgetReqParam("name", params, fields);
|
||||
JSgetReqParam("describe", params, fields);
|
||||
JSgetReqParam("is_open", params, fields);
|
||||
if (fields.size() <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fields.set("update_time", Utils::timeNowStr());
|
||||
|
||||
auto dao = DAO::get("permission");
|
||||
std::string sqlC = " WHERE permission_id='" + permissionId.toStdString() + "'";
|
||||
bool ret = dao->updateFields(fields, sqlC);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
|
||||
// ================================================================================================================
|
||||
// 设备管理接口
|
||||
QVariantMap MyWebHandler::queryDeviceList(int page, int pageSize)
|
||||
{
|
||||
XLOGD() << "queryDeviceList:";
|
||||
|
||||
std::vector<DataFields> res;
|
||||
auto dao = DAO::get("device");
|
||||
bool ret = dao->exec("SELECT * FROM device;", res);
|
||||
XLOGD() << "queryDeviceList: size=" << res.size();
|
||||
|
||||
QVariantMap result;
|
||||
JSsetResPaginaion(result, res, page, pageSize, res.size(), 0, "操作成功");
|
||||
return result;
|
||||
}
|
||||
|
||||
int MyWebHandler::insertDevice(QVariantMap params)
|
||||
{
|
||||
DataFields fields;
|
||||
JSgetReqParam("type", params, fields);
|
||||
JSgetReqParam("name", params, fields);
|
||||
JSgetReqParam("code", params, fields);
|
||||
JSgetReqParam("model", params, fields);
|
||||
JSgetReqParam("factory", params, fields);
|
||||
JSgetReqParam("is_open", params, fields);
|
||||
if (fields.size() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fields.set("create_time", Utils::timeNowStr());
|
||||
fields.set("update_time", Utils::timeNowStr());
|
||||
|
||||
auto dao = DAO::get("device");
|
||||
bool ret = dao->insertFields(fields);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
int MyWebHandler::deleteDevice(const QString& deviceId) { return 1; }
|
||||
int MyWebHandler::updateDevice(const QString& deviceId, QVariantMap params)
|
||||
{
|
||||
DataFields fields;
|
||||
JSgetReqParam("type", params, fields);
|
||||
JSgetReqParam("name", params, fields);
|
||||
JSgetReqParam("code", params, fields);
|
||||
JSgetReqParam("model", params, fields);
|
||||
JSgetReqParam("factory", params, fields);
|
||||
JSgetReqParam("is_open", params, fields);
|
||||
if (fields.size() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fields.set("update_time", Utils::timeNowStr());
|
||||
|
||||
auto dao = DAO::get("device");
|
||||
std::string sqlC = "WHERE device_id='" + deviceId.toStdString() + "'";
|
||||
auto ret = dao->updateFields(fields, sqlC);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
QVariantList MyWebHandler::queryDeviceTypeList()
|
||||
{
|
||||
const std::vector<std::pair<int, std::string>> vecTypeDef =
|
||||
{
|
||||
{1, "光伏设备"},
|
||||
{2, "储能设备"},
|
||||
{3, "充电设备"},
|
||||
{4, "逆变器"},
|
||||
{5, "汇流箱"},
|
||||
{6, "电表"},
|
||||
};
|
||||
|
||||
QVariantList result;
|
||||
for (auto& item: vecTypeDef)
|
||||
{
|
||||
QVariantMap row;
|
||||
row["id"] = item.first;
|
||||
row["name"] = item.second.c_str();
|
||||
result << row;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// ================================================================================================================
|
||||
// 计费管理接口
|
||||
QVariantMap MyWebHandler::queryPriceList(int page, int pageSize)
|
||||
{
|
||||
std::vector<DataFields> res;
|
||||
auto dao = DAO::get("price");
|
||||
bool ret = dao->exec("SELECT * FROM price;", res);
|
||||
XLOGD() << "queryPriceList: size=" << res.size();
|
||||
|
||||
QVariantMap result;
|
||||
JSsetResPaginaion(result, res, page, pageSize, res.size(), 0, "操作成功");
|
||||
return result;
|
||||
}
|
||||
int MyWebHandler::insertPrice(QVariantMap params)
|
||||
{
|
||||
DataFields fields;
|
||||
JSgetReqParam("type", params, fields);
|
||||
JSgetReqParam("describe", params, fields);
|
||||
JSgetReqParam("is_open", params, fields);
|
||||
if (fields.size() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fields.set("create_time", Utils::timeNowStr());
|
||||
fields.set("update_time", Utils::timeNowStr());
|
||||
|
||||
auto dao = DAO::get("price");
|
||||
bool ret = dao->insertFields(fields);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
int MyWebHandler::deletePrice(const QString& priceId) { return 1; }
|
||||
int MyWebHandler::updatePrice(const QString& priceId, QVariantMap params)
|
||||
{
|
||||
DataFields fields;
|
||||
JSgetReqParam("name", params, fields);
|
||||
JSgetReqParam("type", params, fields);
|
||||
JSgetReqParam("describe", params, fields);
|
||||
JSgetReqParam("is_open", params, fields);
|
||||
if (fields.size() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fields.set("update_time", Utils::timeNowStr());
|
||||
|
||||
std::string sqlC = "WHERE price_id='" + priceId.toStdString() + "'";
|
||||
auto dao = DAO::get("price");
|
||||
auto ret = dao->updateFields(fields, sqlC);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
|
||||
QVariantList MyWebHandler::queryPriceTypeList()
|
||||
{
|
||||
const std::vector<std::pair<int, std::string>> vecTypeDef =
|
||||
{
|
||||
{1, "充电计费"},
|
||||
};
|
||||
|
||||
QVariantList result;
|
||||
for (auto& item: vecTypeDef)
|
||||
{
|
||||
QVariantMap row;
|
||||
row["id"] = item.first;
|
||||
row["name"] = item.second.c_str();
|
||||
result << row;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QVariantMap MyWebHandler::queryPolicyList(int page, int pageSize)
|
||||
{
|
||||
std::vector<DataFields> res;
|
||||
auto dao = DAO::get("policy");
|
||||
bool ret = dao->exec("SELECT * FROM policy;", res);
|
||||
XLOGD() << "queryPolicyList: size=" << res.size();
|
||||
|
||||
QVariantMap result;
|
||||
JSsetResPaginaion(result, res, page, pageSize, res.size(), 0, "操作成功");
|
||||
return result;
|
||||
}
|
||||
|
||||
int MyWebHandler::insertPolicy(QVariantMap params)
|
||||
{
|
||||
DataFields fields;
|
||||
JSgetReqParam("type", params, fields);
|
||||
JSgetReqParam("name", params, fields);
|
||||
JSgetReqParam("value", params, fields);
|
||||
JSgetReqParam("describe", params, fields);
|
||||
JSgetReqParam("is_open", params, fields);
|
||||
if (fields.size() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fields.set("create_time", Utils::timeNowStr());
|
||||
fields.set("update_time", Utils::timeNowStr());
|
||||
|
||||
auto dao = DAO::get("policy");
|
||||
bool ret = dao->insertFields(fields);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
|
||||
int MyWebHandler::deletePolicy(const QString& policyId) { return 1; }
|
||||
|
||||
int MyWebHandler::updatePolicy(const QString& policyId, QVariantMap params)
|
||||
{
|
||||
DataFields fields;
|
||||
JSgetReqParam("type", params, fields);
|
||||
JSgetReqParam("name", params, fields);
|
||||
JSgetReqParam("value", params, fields);
|
||||
JSgetReqParam("describe", params, fields);
|
||||
JSgetReqParam("is_open", params, fields);
|
||||
if (fields.size() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fields.set("update_time", Utils::timeNowStr());
|
||||
|
||||
std::string sqlC = "WHERE policy_id='" + policyId.toStdString() + "'";
|
||||
auto dao = DAO::get("policy");
|
||||
auto ret = dao->updateFields(fields, sqlC);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
|
||||
QVariantList MyWebHandler::queryPolicyTypeList()
|
||||
{
|
||||
const std::vector<std::pair<int, std::string>> vecTypeDef =
|
||||
{
|
||||
{1, "发电策略"},
|
||||
{2, "储能策略"},
|
||||
{3, "充电策略"},
|
||||
};
|
||||
|
||||
QVariantList result;
|
||||
for (auto& item: vecTypeDef)
|
||||
{
|
||||
QVariantMap row;
|
||||
row["id"] = item.first;
|
||||
row["name"] = item.second.c_str();
|
||||
result << row;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
QVariantMap MyWebHandler::querySyslogList(int page, int pageSize)
|
||||
{
|
||||
std::vector<DataFields> res;
|
||||
auto dao = DAO::get("system_log");
|
||||
bool ret = dao->exec("SELECT * FROM system_log;", res);
|
||||
XLOGD() << "querySyslogList: size=" << res.size();
|
||||
|
||||
QVariantMap result;
|
||||
JSsetResPaginaion(result, res, page, pageSize, res.size(), 0, "操作成功");
|
||||
return result;
|
||||
}
|
||||
|
||||
QVariantMap MyWebHandler::querySecPolicyList(int page, int pageSize)
|
||||
{
|
||||
std::vector<DataFields> res;
|
||||
auto dao = DAO::get("sec_policy");
|
||||
bool ret = dao->exec("SELECT * FROM sec_policy;", res);
|
||||
XLOGD() << "querySecPolicyList: size=" << res.size();
|
||||
|
||||
QVariantMap result;
|
||||
JSsetResPaginaion(result, res, page, pageSize, res.size(), 0, "操作成功");
|
||||
return result;
|
||||
}
|
||||
|
||||
int MyWebHandler::insertSecPolicy(QVariantMap params)
|
||||
{
|
||||
DataFields fields;
|
||||
JSgetReqParam("name", params, fields);
|
||||
JSgetReqParam("type", params, fields);
|
||||
JSgetReqParam("code", params, fields);
|
||||
JSgetReqParam("level", params, fields);
|
||||
JSgetReqParam("describe", params, fields);
|
||||
JSgetReqParam("action", params, fields);
|
||||
JSgetReqParam("is_open", params, fields);
|
||||
if (fields.size() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fields.set("create_time", Utils::timeNowStr());
|
||||
fields.set("update_time", Utils::timeNowStr());
|
||||
|
||||
auto dao = DAO::get("sec_policy");
|
||||
bool ret = dao->insertFields(fields);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
|
||||
int MyWebHandler::updateSecPolicy(const QString& policyId, QVariantMap params)
|
||||
{
|
||||
DataFields fields;
|
||||
JSgetReqParam("name", params, fields);
|
||||
JSgetReqParam("type", params, fields);
|
||||
JSgetReqParam("code", params, fields);
|
||||
JSgetReqParam("level", params, fields);
|
||||
JSgetReqParam("describe", params, fields);
|
||||
JSgetReqParam("action", params, fields);
|
||||
JSgetReqParam("is_open", params, fields);
|
||||
if (fields.size() == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
fields.set("update_time", Utils::timeNowStr());
|
||||
|
||||
std::string sqlC = "WHERE sec_policy_id='" + policyId.toStdString() + "'";
|
||||
auto dao = DAO::get("sec_policy");
|
||||
auto ret = dao->updateFields(fields, sqlC);
|
||||
return ret ? 0 : 1;
|
||||
}
|
||||
|
||||
QVariantMap MyWebHandler::querySecRecordList(int page, int pageSize)
|
||||
{
|
||||
std::vector<DataFields> res;
|
||||
auto dao = DAO::get("sec_record");
|
||||
bool ret = dao->exec("SELECT * FROM sec_record;", res);
|
||||
XLOGD() << "querySecRecordList: size=" << res.size();
|
||||
|
||||
QVariantMap result;
|
||||
JSsetResPaginaion(result, res, page, pageSize, res.size(), 0, "操作成功");
|
||||
return result;
|
||||
};
|
||||
|
||||
int MyWebHandler::insertSecRecord(QVariantMap params) {};
|
||||
int MyWebHandler::updateSecRecord(const QString& policyId, QVariantMap params) {};
|
||||
106
src/widgets/WebHandler.h
Normal file
106
src/widgets/WebHandler.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QVariantMap>
|
||||
#include <QVariantList>
|
||||
|
||||
class MyWebHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
//Q_PROPERTY(QString nativeText READ nativeText MEMBER m_nativeText NOTIFY signalNativeTextChanged FINAL)
|
||||
|
||||
public:
|
||||
explicit MyWebHandler(QObject* parent = nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
QString nativeText() const { return nativeText_; }
|
||||
|
||||
|
||||
signals:
|
||||
//在C++中定义的信号,可以在JS端监听此信号接收消息
|
||||
void signalNativeTextChanged(const QString& text);
|
||||
|
||||
void singalReadFileFinished(const QString& text);
|
||||
|
||||
public slots:
|
||||
//C++ 端的公共槽函数,可以在JS端调用。
|
||||
void setNativeText(const QString& text);
|
||||
|
||||
void log(const QString& text);
|
||||
|
||||
QString readFile(const QString& filename);
|
||||
|
||||
// ================================================================================================================
|
||||
// 用户管理接口
|
||||
QVariantMap queryUserList(int page, int pageSize);
|
||||
int insertUser(QVariantMap params);
|
||||
int deleteUser(const QString& userId);
|
||||
int updateUser(const QString& userId, QVariantMap params);
|
||||
|
||||
// ================================================================================================================
|
||||
// 角色管理接口
|
||||
/**
|
||||
* 查询角色列表, pageSize !=0 时分页查询
|
||||
* @param [int page]: 当前的页码
|
||||
* @param [int pageSize]: 一页的数据条数,0: 不分页; >0: 分页
|
||||
*/
|
||||
QVariantMap queryRoleList(int page, int pageSize);
|
||||
int insertRole(QVariantMap params);
|
||||
int deleteRole(const QString& roleId);
|
||||
int updateRole(const QString& roleId, QVariantMap params);
|
||||
|
||||
QVariantList queryRolePermissionList(int roleId);
|
||||
int updateRolePermission(int roleId, QVariantList params);
|
||||
|
||||
// ================================================================================================================
|
||||
// 权限管理接口
|
||||
QVariantMap queryPermissionList(int page, int pageSize);
|
||||
int insertPermission(QVariantMap params);
|
||||
int deletePermission(const QString& permissionId);
|
||||
int updatePermission(const QString& permissionId, QVariantMap params);
|
||||
|
||||
// ================================================================================================================
|
||||
// 设备管理接口
|
||||
QVariantMap queryDeviceList(int page, int pageSize);
|
||||
int insertDevice(QVariantMap params);
|
||||
int deleteDevice(const QString& deviceId);
|
||||
int updateDevice(const QString& deviceId, QVariantMap params);
|
||||
QVariantList queryDeviceTypeList();
|
||||
|
||||
// ================================================================================================================
|
||||
// 计费管理接口
|
||||
QVariantMap queryPriceList(int page, int pageSize);
|
||||
int insertPrice(QVariantMap params);
|
||||
int deletePrice(const QString& priceId);
|
||||
int updatePrice(const QString& priceId, QVariantMap params);
|
||||
QVariantList queryPriceTypeList();
|
||||
|
||||
// ================================================================================================================
|
||||
// 策略管理接口
|
||||
QVariantMap queryPolicyList(int page, int pageSize);
|
||||
int insertPolicy(QVariantMap params);
|
||||
int deletePolicy(const QString& policyId);
|
||||
int updatePolicy(const QString& policyId, QVariantMap params);
|
||||
QVariantList queryPolicyTypeList();
|
||||
|
||||
// ================================================================================================================
|
||||
// 系统日志接口
|
||||
QVariantMap querySyslogList(int page, int pageSize);
|
||||
|
||||
// ================================================================================================================
|
||||
// 安全策略
|
||||
QVariantMap querySecPolicyList(int page, int pageSize);
|
||||
int insertSecPolicy(QVariantMap params);
|
||||
int updateSecPolicy(const QString& policyId, QVariantMap params);
|
||||
|
||||
// ================================================================================================================
|
||||
// 安全日志记录
|
||||
QVariantMap querySecRecordList(int page, int pageSize);
|
||||
int insertSecRecord(QVariantMap params);
|
||||
int updateSecRecord(const QString& policyId, QVariantMap params);
|
||||
|
||||
public:
|
||||
QString nativeText_;
|
||||
};
|
||||
78
src/widgets/WidgetLogin.cpp
Normal file
78
src/widgets/WidgetLogin.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "WidgetLogin.h"
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
#include "app/Application.h"
|
||||
|
||||
WidgetLogin::WidgetLogin()
|
||||
{
|
||||
this->resize(1920, 1080);
|
||||
|
||||
|
||||
QUI::label(labBkg_, this, 0, 0, 1920, 1080, "");
|
||||
labBkg_.setPixmap(QPixmap("assets/ui/bkgLogin.png"));
|
||||
|
||||
int w = 517;
|
||||
int h = 534;
|
||||
int x = (1920 - w) *0.5;
|
||||
int y = (1080 - h) *0.5;
|
||||
|
||||
//QUI::label(labLoginBkg_, this, x, y, w, h, "");
|
||||
//labLoginBkg_.setPixmap(QPixmap("assets/ui/login.png"));
|
||||
|
||||
|
||||
QUI::lineedit(lineUsername_, this, 870, 447, 300, 36);
|
||||
QUI::lineedit(linePasswd_, this, 870, 510, 300, 36);
|
||||
|
||||
std::string sty = "QLineEdit {"
|
||||
" background-color: #2859b0;" // 背景颜色
|
||||
" color: #ffffff;" // 文字颜色
|
||||
" border: 0px solid #ccc;" // 边框
|
||||
" border-radius: 5px;" // 圆角
|
||||
" padding: 5px;" // 内边距
|
||||
" font-size: 16px;" // 字体大小
|
||||
" font-weight: bold;" // 字体加粗
|
||||
"}";
|
||||
lineUsername_.setStyleSheet(sty.c_str());
|
||||
linePasswd_.setStyleSheet(sty.c_str());
|
||||
|
||||
// 提示信息框
|
||||
QUI::label(labMsg_, this, 838, 630, 350, 36, "");
|
||||
|
||||
// 登录按钮
|
||||
QUI::button(btnLoigin_, this, 838, 588, 338, 46, "登 入", "background-color:#2a82e4; color:white;font-size: 14px;font-weight:bold;");
|
||||
QObject::connect(&btnLoigin_, &QPushButton::clicked, this, &WidgetLogin::slotBtnCilckLogin);
|
||||
}
|
||||
|
||||
|
||||
void WidgetLogin::slotBtnCilckLogin()
|
||||
{
|
||||
if (0)
|
||||
{
|
||||
std::string account = lineUsername_.text().toStdString();
|
||||
std::string passwd = linePasswd_.text().toStdString();
|
||||
std::string err;
|
||||
|
||||
if (account.empty())
|
||||
{
|
||||
labMsg_.setText(std::string("请输入用户名" + err).c_str());
|
||||
return;
|
||||
}
|
||||
if (passwd.empty())
|
||||
{
|
||||
labMsg_.setText(std::string("请输入用密码" + err).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
auto& op = Application::instance().getOperator();
|
||||
bool ret = op.login(account, passwd, err);
|
||||
if (!ret)
|
||||
{
|
||||
labMsg_.setText(std::string("登录失败:" + err).c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查登录用户名和密码
|
||||
emit signalLoginSuccess();
|
||||
}
|
||||
31
src/widgets/WidgetLogin.h
Normal file
31
src/widgets/WidgetLogin.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "uihelper.h"
|
||||
|
||||
class WidgetLogin : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WidgetLogin();
|
||||
|
||||
signals:
|
||||
void signalLoginSuccess();
|
||||
|
||||
public slots:
|
||||
void slotBtnCilckLogin();
|
||||
|
||||
|
||||
|
||||
public:
|
||||
QLabel labBkg_;
|
||||
QLabel labLoginBkg_;
|
||||
|
||||
QLineEdit lineUsername_;
|
||||
QLineEdit linePasswd_;
|
||||
|
||||
QLabel labMsg_;
|
||||
|
||||
QPushButton btnLoigin_;
|
||||
};
|
||||
25
src/widgets/WidgetPage.cpp
Normal file
25
src/widgets/WidgetPage.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "WidgetPage.h"
|
||||
|
||||
#include "pages/WidgetPageHome.h"
|
||||
#include "pages/WidgetPageOverview.h"
|
||||
#include "pages/WidgetPageRunning.h"
|
||||
#include "pages/WidgetPageWeb.h"
|
||||
|
||||
std::shared_ptr<WidgetPage> WidgetPage::create(QWidget* parent, std::string name)
|
||||
{
|
||||
std::shared_ptr<WidgetPage> w = nullptr;
|
||||
if (name == "系统总览")
|
||||
{
|
||||
w = std::make_shared<WidgetPageOverview>(parent);
|
||||
}
|
||||
else if (name == "运行监控")
|
||||
{
|
||||
w = std::make_shared<WidgetPageRunning>(parent);
|
||||
}
|
||||
else
|
||||
{
|
||||
w = std::make_shared<WidgetPageWeb>(parent, name);
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
17
src/widgets/WidgetPage.h
Normal file
17
src/widgets/WidgetPage.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "uihelper.h"
|
||||
|
||||
|
||||
class WidgetPage : public QWidget
|
||||
{
|
||||
public:
|
||||
static std::shared_ptr<WidgetPage> create(QWidget* parent, std::string name);
|
||||
|
||||
WidgetPage(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void updateData() {};
|
||||
|
||||
};
|
||||
41
src/widgets/WidgetWeb.cpp
Normal file
41
src/widgets/WidgetWeb.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "WidgetWeb.h"
|
||||
|
||||
WebHandler::WebHandler(QObject* parent)
|
||||
: QObject {parent}
|
||||
{
|
||||
webChannel = new QWebChannel();
|
||||
// 注册C++对象到QWebChannel,这样远端的QWebChannel也会生成一个对应的JS对象
|
||||
// 在JS中引入 qwebchannel.js, 使用 channel.objects.webNative 获取注册的“webNative”
|
||||
webChannel->registerObject("webNative", this);
|
||||
}
|
||||
|
||||
void WebHandler::setNativeText(const QString& text)
|
||||
{
|
||||
m_nativeText = text;
|
||||
qDebug() << QString("setNativeText:") << text;
|
||||
emit signalNativeTextChanged(text);
|
||||
}
|
||||
|
||||
WidgetWeb::WidgetWeb(QWidget* parent) : QWebEngineView(parent)
|
||||
{
|
||||
webHandler_ = new WebHandler();
|
||||
this->page()->setWebChannel(webHandler_->webChannel);
|
||||
this->setContextMenuPolicy(Qt::NoContextMenu);
|
||||
}
|
||||
|
||||
void WidgetWeb::loadHtml(std::string url)
|
||||
{
|
||||
// "file:///assets/html/echarts//maptest.html"
|
||||
this->load(QUrl(url.c_str()));
|
||||
connect(this, &QWebEngineView::loadFinished, this, &WidgetWeb::slotLoadFinished);
|
||||
}
|
||||
|
||||
void WidgetWeb::invikeJS(QString jscode)
|
||||
{
|
||||
//QString jscode = QString("showalert('%1')").arg("Hello QtWebEngine!");
|
||||
this->page()->runJavaScript(jscode, [](const QVariant& v) { qDebug() << v.toString(); });
|
||||
}
|
||||
|
||||
void WidgetWeb::slotLoadFinished(bool ret)
|
||||
{
|
||||
}
|
||||
48
src/widgets/WidgetWeb.h
Normal file
48
src/widgets/WidgetWeb.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWebChannel>
|
||||
#include <QtWebEngineWidgets/QWebEngineView>
|
||||
#include <string>
|
||||
|
||||
class WebHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString nativeText READ nativeText MEMBER m_nativeText NOTIFY signalNativeTextChanged FINAL)
|
||||
|
||||
public:
|
||||
explicit WebHandler(QObject* parent = nullptr);
|
||||
|
||||
QString nativeText() const { return m_nativeText; }
|
||||
|
||||
signals:
|
||||
//在C++中定义的信号,可以在JS端监听此信号接收消息
|
||||
void signalNativeTextChanged(const QString& text);
|
||||
|
||||
public slots:
|
||||
//C++ 端的公共槽函数,可以在JS端调用。
|
||||
void setNativeText(const QString& text);
|
||||
|
||||
public:
|
||||
QString m_nativeText;
|
||||
QWebChannel* webChannel;
|
||||
};
|
||||
|
||||
|
||||
class WidgetWeb : public QWebEngineView
|
||||
{
|
||||
public:
|
||||
WidgetWeb(QWidget* parent);
|
||||
|
||||
void loadHtml(std::string url);
|
||||
|
||||
void invikeJS(QString jscode);
|
||||
|
||||
// slots
|
||||
void slotLoadFinished(bool ret);
|
||||
|
||||
|
||||
|
||||
public:
|
||||
WebHandler* webHandler_;
|
||||
|
||||
};
|
||||
0
src/widgets/pages/WidgetPageDevice.cpp
Normal file
0
src/widgets/pages/WidgetPageDevice.cpp
Normal file
0
src/widgets/pages/WidgetPageDevice.h
Normal file
0
src/widgets/pages/WidgetPageDevice.h
Normal file
203
src/widgets/pages/WidgetPageHome.cpp
Normal file
203
src/widgets/pages/WidgetPageHome.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
#include "WidgetPageHome.h"
|
||||
|
||||
#include "common/TimeUtils.h"
|
||||
#include "common/Utils.h"
|
||||
|
||||
static std::vector<double> RANDT(int n, int min, int max)
|
||||
{
|
||||
std::vector<double> v(n);
|
||||
for (int i = 0; i<n; i++) { v[i] = Utils::random(min, max); }
|
||||
return v;
|
||||
}
|
||||
|
||||
class InfoItem : public QWidget
|
||||
{
|
||||
public:
|
||||
QLabel labTitle_;
|
||||
QLabel labVal_;
|
||||
QLabel labUnit_;
|
||||
|
||||
InfoItem::InfoItem(QWidget* parent, QRect rt, std::string title, std::string unit, std::string v="")
|
||||
: QWidget(parent)
|
||||
{
|
||||
this->setGeometry(rt);
|
||||
QUI::setBackground(this, "InfoCardItem", QColor(200, 200, 200, 30));
|
||||
|
||||
int xHalf = rt.width()/2;
|
||||
int yHalf = rt.height()/2;
|
||||
QUI::label(labTitle_, this, 0, 0, rt.width(), yHalf-10, title);
|
||||
labTitle_.setAlignment(Qt::AlignBottom | Qt::AlignHCenter);
|
||||
QUI::label(labVal_, this, 0, yHalf, xHalf+20, 30, v, "font:bold 24px;color:rgb(38,220,172);");
|
||||
labVal_.setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
QUI::label(labUnit_, this, xHalf+30, yHalf, 30, 30, unit);
|
||||
}
|
||||
|
||||
void InfoItem::setVal(std::string v)
|
||||
{
|
||||
labVal_.setText(v.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
class EnvItem
|
||||
{
|
||||
public:
|
||||
QLabel labBkg_;
|
||||
QLabel labIcon_;
|
||||
QLabel labVal_;
|
||||
|
||||
EnvItem(QWidget* parent, int x, int y, std::string icon, std::string v)
|
||||
{
|
||||
QUI::label(labBkg_, parent, x, y, 60, 60, "", "background-color:rgb(42, 74, 132);border-radius:30px;");
|
||||
QUI::label(labIcon_, parent, x+6, y+6, 48, 48, "");
|
||||
labIcon_.setPixmap(QPixmap(icon.c_str()));
|
||||
QUI::label(labVal_, parent, x-10, y+65, 80, 40, v, "font:bold 14px;color:white;");
|
||||
labVal_.setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
};
|
||||
void WidgetPageHome::slotLoadFinished(bool bOK)
|
||||
{
|
||||
QString jsCode = QString("showalert('%1')").arg("Hello QtWebEngine!");
|
||||
wWebView->page()->runJavaScript(jsCode, [](const QVariant& v) { qDebug() << v.toString(); });
|
||||
}
|
||||
WidgetPageHome::WidgetPageHome(QWidget* parent) : WidgetPage(parent)
|
||||
{
|
||||
const std::string STY_VAL = "font:bold 18px;color:rgb(38,220,172);";
|
||||
const int H = 300;
|
||||
|
||||
// 地图
|
||||
//QUI::label(labMapBkg_, this, 500, 10, 920, H*3-10, "");
|
||||
//labMapBkg_.setPixmap(QPixmap("assets/ui/bkg_map.png"));
|
||||
|
||||
wWebView = std::make_shared<QWebEngineView>(this);
|
||||
wWebView->setGeometry(500, 10, 920, H*3-10);
|
||||
|
||||
wWebView->setContextMenuPolicy(Qt::NoContextMenu);
|
||||
//webEngineView.load(QUrl("https://www.baidu.com"));
|
||||
wWebView->load(QUrl("file:///assets/echarts/HTML/maptest.html"));
|
||||
|
||||
connect(wWebView.get(), &QWebEngineView::loadFinished, this, &WidgetPageHome::slotLoadFinished);
|
||||
|
||||
//std::string htmlContent = "HelloWorld";
|
||||
//webEngineView.setHtml(htmlContent.c_str());
|
||||
wWebView->show();
|
||||
|
||||
panelStation_ = std::make_shared<Panel>(this, QRect(10, 10, 480, H-10), "信息概览");
|
||||
{
|
||||
QWidget* wParent = panelStation_.get();
|
||||
infoNum1_ = std::make_shared<InfoItem>(wParent, QRect(20, 50, 210, 100), "风电设备数量", "台", "5");
|
||||
infoNum2_ = std::make_shared<InfoItem>(wParent, QRect(240, 50, 210, 100), "光伏设备数量", "台", "27");
|
||||
infoNum3_ = std::make_shared<InfoItem>(wParent, QRect(20, 160, 210, 100), "储能设备", "台", "16");
|
||||
infoNum4_ = std::make_shared<InfoItem>(wParent, QRect(240, 160, 210, 100), "充电设备", "台", "12");
|
||||
}
|
||||
|
||||
panelStat_ = std::make_shared<Panel>(this, QRect(10, 10+H, 480, H-10), "统计信息");
|
||||
{
|
||||
int x = 40; int y = 50;
|
||||
int w = 180;
|
||||
int h = 60; int h1 = 40;
|
||||
QWidget* wParent = panelStat_.get();
|
||||
labSwapCount_ = QUI::labelPairV(wParent, x, y, w, h, h1, "风电今日发电量", "100.000");
|
||||
labElectCount_ = QUI::labelPairV(wParent, x + 200, y, w, h, h1, "风电累计发电量", "100.000");
|
||||
labSwapCountDay_ = QUI::labelPairV(wParent, x, y += (h+10), w, h, h1, "光伏今日发电量", "100.000");
|
||||
labElectCountDay_ = QUI::labelPairV(wParent, x+ 200, y, w, h, h1, "光伏累计发电量", "100.000");
|
||||
labCarbonCount_ = QUI::labelPairV(wParent, x, y += (h+10), w, h, h1, "信息5", "100.000");
|
||||
labP1_ = QUI::labelPairV(wParent, x+ 200, y, w, h, h1, "信息4", "100.000");
|
||||
}
|
||||
|
||||
|
||||
panelEnv_ = std::make_shared<Panel>(this, QRect(10, 10+H*2, 480, H-10), "环境信息");
|
||||
{
|
||||
QWidget* wParent = panelEnv_.get();
|
||||
|
||||
int x = 40;
|
||||
int y = 50;
|
||||
|
||||
envTemperature_ = std::make_shared<EnvItem>(wParent, x, y, "./assets/ui/temperature.png", "温度\n31℃");
|
||||
envHumidity_ = std::make_shared<EnvItem>(wParent, x+100, y, "./assets/ui/humidity.png", "湿度\n42%");
|
||||
envWind_ = std::make_shared<EnvItem>(wParent, x+200, y, "./assets/ui/windsSolid.png", "风速\n1.5m/s");
|
||||
envSolar_ = std::make_shared<EnvItem>(wParent, x+300, y, "./assets/ui/brightness.png", "辐照度\n120W/m2");
|
||||
|
||||
y += 120;
|
||||
QUI::label(labProgressCpu_, wParent, 40, y, 100, 24, "CPU使用率");
|
||||
progressCpu_ = std::make_shared<ProgressView>(wParent, 120, y, 24);
|
||||
progressCpu_->setVal(30);
|
||||
|
||||
y += 40;
|
||||
QUI::label(labProgressMem_, wParent, 40, y, 100, 24, "内存使用率");
|
||||
progressMem_ = std::make_shared<ProgressView>(wParent, 120, y, 24);
|
||||
progressMem_->setVal(60);
|
||||
|
||||
y += 40;
|
||||
QUI::label(labProgressDisk_, wParent, 40, y, 100, 24, "磁盘使用率");
|
||||
progressDisk_ = std::make_shared<ProgressView>(wParent, 120, y, 24);
|
||||
progressDisk_->setVal(60);
|
||||
}
|
||||
|
||||
int y = 10;
|
||||
int h = 280;
|
||||
panelSwap_ = std::make_shared<Panel>(this, QRect(1430, 10+H*0, 480, H-10), "信息1");
|
||||
{
|
||||
//chartbar1_ = std::make_shared<ChartBarView>(panelSwap_.get(), QRect(0, 30, 480, h-20), 7);
|
||||
//chartbar1_->addItem("数据1");
|
||||
//chartbar1_->addItem("数据2");
|
||||
//chartbar1_->addItem("数据3");
|
||||
//chartbar1_->addItem("数据4");
|
||||
}
|
||||
|
||||
y += (h+10);
|
||||
panel2_ = std::make_shared<Panel>(this, QRect(1430, 10+H*1, 480, H-10), "信息2");
|
||||
{
|
||||
//chartbar2_ = std::make_shared<ChartBarView>(panel2_.get(), QRect(0, 30, 480, h-20), 7);
|
||||
//chartbar2_->addItem("数据1");
|
||||
//chartbar2_->addItem("数据2");
|
||||
//chartbar2_->addItem("数据3");
|
||||
}
|
||||
|
||||
y += (h+10);
|
||||
panel3_ = std::make_shared<Panel>(this, QRect(1430, 10+H*2, 480, H-10), "信息3");
|
||||
{
|
||||
chartbar3_ = std::make_shared<ChartBarView>(panel3_.get(), QRect(0, 30, 480, h-20), 7);
|
||||
chartbar3_->addItem("数据1");
|
||||
chartbar3_->addItem("数据2");
|
||||
|
||||
// 测试数据
|
||||
//chartbar3_->updateItem(0, RANDT(7, 1, 10));
|
||||
//chartbar3_->updateItem(1, RANDT(7, 1, 10));
|
||||
}
|
||||
|
||||
|
||||
//chartbar1_->updateItem(0, RANDT(7, 1, 10));
|
||||
//chartbar1_->updateItem(1, RANDT(7, 1, 10));
|
||||
//chartbar1_->updateItem(2, RANDT(7, 1, 10));
|
||||
//chartbar1_->updateItem(3, RANDT(7, 1, 10));
|
||||
|
||||
//chartbar2_->updateItem(0, RANDT(7, 1, 10));
|
||||
//chartbar2_->updateItem(1, RANDT(7, 1, 10));
|
||||
//chartbar2_->updateItem(2, RANDT(7, 1, 10));
|
||||
|
||||
|
||||
|
||||
//panelPower_ = std::make_shared<Panel>(this, QRect(500, 590, 920, 280), "今日负荷曲线");
|
||||
//{
|
||||
// QWidget* wParent = panelPower_.get();
|
||||
// chartline7_ = std::make_shared<ChartLineView>(wParent, QRect(10, 30, 900, 240));
|
||||
// chartline7_->addItem("数据1");
|
||||
// chartline7_->addItem("数据2");
|
||||
// chartline7_->setAxisYLeft(-1, 1, 7);
|
||||
|
||||
// //double t0 = TimeUtils::datetime2tms(TimeUtils::now_date() + " 00:00:00");
|
||||
// //double tx = t0;
|
||||
// //int n = 360;
|
||||
// //std::vector<std::pair<double, double>> vd0(n+1);
|
||||
// //std::vector<std::pair<double, double>> vd1(n+1);
|
||||
// //for (int i = 0; i<=n; i++)
|
||||
// //{
|
||||
// // tx = t0 + i*(86400/n)*1000;
|
||||
// // vd0[i] = {tx, sin(2*3.1415926*float(i*2)/float(360))};
|
||||
// // vd1[i] = {tx, cos(2*3.1415926*float(i*2)/float(360))};
|
||||
// //}
|
||||
// //chartline7_->setAxisX(t0, tx, 13, "hh:mm");
|
||||
// //chartline7_->updateItem(0, vd0);
|
||||
// //chartline7_->updateItem(1, vd1);
|
||||
//}
|
||||
};
|
||||
64
src/widgets/pages/WidgetPageHome.h
Normal file
64
src/widgets/pages/WidgetPageHome.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include "WidgetPage.h"
|
||||
|
||||
#include <QtWebEngineWidgets/QWebEngineView>
|
||||
class InfoItem;
|
||||
class EnvItem;
|
||||
|
||||
class WidgetPageHome : public WidgetPage
|
||||
{
|
||||
public:
|
||||
WidgetPageHome(QWidget* parent);
|
||||
void slotLoadFinished(bool bOK);
|
||||
|
||||
QLabel labTitle_;
|
||||
|
||||
QLabel labMapBkg_;
|
||||
|
||||
std::shared_ptr<Panel> panelStation_;
|
||||
std::shared_ptr<InfoItem> infoNum2_;
|
||||
std::shared_ptr<InfoItem> infoNum1_;
|
||||
std::shared_ptr<InfoItem> infoNum3_;
|
||||
std::shared_ptr<InfoItem> infoNum4_;
|
||||
|
||||
|
||||
std::shared_ptr<Panel> panelSwap_;
|
||||
std::shared_ptr<ChartBarView> chartbar1_;
|
||||
|
||||
std::shared_ptr<Panel> panel2_;
|
||||
std::shared_ptr<ChartBarView> chartbar2_;
|
||||
|
||||
std::shared_ptr<Panel> panel3_;
|
||||
std::shared_ptr<ChartBarView> chartbar3_;
|
||||
|
||||
|
||||
std::shared_ptr<Panel> panelStat_;
|
||||
std::shared_ptr<LabelPairV> labSwapCount_;
|
||||
std::shared_ptr<LabelPairV> labSwapCountDay_;
|
||||
std::shared_ptr<LabelPairV> labElectCount_;
|
||||
std::shared_ptr<LabelPairV> labElectCountDay_;
|
||||
std::shared_ptr<LabelPairV> labCarbonCount_;
|
||||
std::shared_ptr<LabelPairV> labP1_;
|
||||
|
||||
std::shared_ptr<Panel> panelEnv_;
|
||||
std::shared_ptr<Panel> panelPower_;
|
||||
|
||||
QLabel labProgressCpu_;
|
||||
std::shared_ptr<ProgressView> progressCpu_;
|
||||
|
||||
QLabel labProgressMem_;
|
||||
std::shared_ptr<ProgressView> progressMem_;
|
||||
|
||||
QLabel labProgressDisk_;
|
||||
std::shared_ptr<ProgressView> progressDisk_;
|
||||
|
||||
std::shared_ptr<EnvItem> envTemperature_;
|
||||
std::shared_ptr<EnvItem> envHumidity_;
|
||||
std::shared_ptr<EnvItem> envWind_;
|
||||
std::shared_ptr<EnvItem> envSolar_;
|
||||
|
||||
std::shared_ptr<ChartLineView> chartline_;
|
||||
|
||||
std::shared_ptr<QWebEngineView> wWebView = nullptr;
|
||||
};
|
||||
173
src/widgets/pages/WidgetPageOverview.cpp
Normal file
173
src/widgets/pages/WidgetPageOverview.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
#include "WidgetPageOverview.h"
|
||||
#include "common/TimeUtils.h"
|
||||
#include "common/Utils.h"
|
||||
static std::vector<double> RANDT(int n, int min, int max)
|
||||
{
|
||||
std::vector<double> v(n);
|
||||
for (int i = 0; i<n; i++) { v[i] = Utils::random(min, max); }
|
||||
return v;
|
||||
}
|
||||
|
||||
WidgetPageOverview::WidgetPageOverview(QWidget* parent) : WidgetPage(parent)
|
||||
{
|
||||
{
|
||||
panel1_ = std::make_shared<Panel>(this, QRect(10, 10, 490, 300), "运行状况");
|
||||
QWidget* wParent = panel1_.get();
|
||||
|
||||
labBkg_ = QUI::label(wParent, 10, 40, 150, 250, "", "border:1px solid rgb(27, 88, 105);background-color:rgba(200,200,200,30)");
|
||||
|
||||
labDaysK_ = QUI::label(wParent, 10, 180, 150, 30, "安全运行时间", "color:white;font: bold 20px;");
|
||||
labDaysK_->setAlignment(Qt::AlignCenter);
|
||||
|
||||
labDaysV_ = QUI::label(wParent, 10, 100, 105, 50, "223", "color:rgb(77, 215, 240);font: bold 40px;");
|
||||
labDaysV_->setAlignment(Qt::AlignBottom | Qt::AlignRight);
|
||||
|
||||
labDaysT_ = QUI::label(wParent, 120, 105, 40, 40, "天", "color:white;font: bold 14px;");
|
||||
labDaysT_->setAlignment(Qt::AlignBottom);
|
||||
|
||||
int x = 170; int y = 40;
|
||||
int w = 150; int h = 77;
|
||||
labp1_ = std::make_shared<LabelParam>(wParent, "站内风机设备", "100", "台", x, y, w, h);
|
||||
labp2_ = std::make_shared<LabelParam>(wParent, "站内光伏设备", "100", "台", x += (w+10), y, w, h);
|
||||
|
||||
labp3_ = std::make_shared<LabelParam>(wParent, "当日入网电量", "31.58", "Kwh", x = 170, y += (h+10), w, h);
|
||||
labp4_ = std::make_shared<LabelParam>(wParent, "累计入网设备", "54763.01", "Kwh", x += (w+10), y, w, h);
|
||||
|
||||
labp5_ = std::make_shared<LabelParam>(wParent, "累计充放电量", "387.13", "台", x = 170, y += (h+10), w, h);
|
||||
labp6_ = std::make_shared<LabelParam>(wParent, "累计碳减排量", "66.72", "吨", x += (w+10), y, w, h);
|
||||
}
|
||||
|
||||
{
|
||||
panel2_ = std::make_shared<Panel>(this, QRect(10, 320, 490, 300), "光伏设备");
|
||||
QWidget* wParent = panel2_.get();
|
||||
|
||||
int x = 10; int y = 40;
|
||||
int w = 150; int h = 50;
|
||||
labp21_ = std::make_shared<LabelParam>(wParent, "日累计发电量", "223", "Kwh", x, y, w, h);
|
||||
labp22_ = std::make_shared<LabelParam>(wParent, "日上网电量", "100", "Kwh", x += (w+10), y, w, h);
|
||||
labp23_ = std::make_shared<LabelParam>(wParent, "日发电时长", "152", "h", x += (w+10), y, w, h);
|
||||
|
||||
chartbar2_ = std::make_shared<ChartBarView>(wParent, QRect(10, 95, 470, 210), 5);
|
||||
chartbar2_->addItem("日累计发电量");
|
||||
chartbar2_->addItem("日上网电量");
|
||||
chartbar2_->addItem("日发电时长");
|
||||
chartbar2_->updateItem(0, RANDT(7, 1, 10));
|
||||
chartbar2_->updateItem(1, RANDT(7, 1, 10));
|
||||
chartbar2_->updateItem(2, RANDT(7, 1, 10));
|
||||
}
|
||||
|
||||
{
|
||||
panel3_ = std::make_shared<Panel>(this, QRect(10, 630, 490, 300), "储能设备");
|
||||
QWidget* wParent = panel3_.get();
|
||||
|
||||
int x = 10; int y = 40;
|
||||
int w = 225; int h = 50;
|
||||
labp31_ = std::make_shared<LabelParam>(wParent, "日累计充电电量", "223.23", "Kwh", x, y, w, h);
|
||||
labp32_ = std::make_shared<LabelParam>(wParent, "日累计放电电量", "123.01", "Kwh", x += (w+20), y, w, h);
|
||||
|
||||
chartbar3_ = std::make_shared<ChartBarView>(wParent, QRect(10, 95, 470, 210), 5);
|
||||
chartbar3_->addItem("日累充电电量");
|
||||
chartbar3_->addItem("日上放电电量");
|
||||
chartbar3_->updateItem(0, RANDT(7, 1, 10));
|
||||
chartbar3_->updateItem(1, RANDT(7, 1, 10));
|
||||
}
|
||||
{
|
||||
panel4_ = std::make_shared<Panel>(this, QRect(1420, 10, 490, 300), "负荷设备");
|
||||
QWidget* wParent = panel4_.get();
|
||||
|
||||
int x = 10; int y = 40;
|
||||
int w = 150; int h = 50;
|
||||
labp41_ = std::make_shared<LabelParam>(wParent, "日用电功率", "223.23", "Kw", x, y, w, h);
|
||||
labp42_ = std::make_shared<LabelParam>(wParent, "日用电次数", "126", "次", x += (w+10), y, w, h);
|
||||
labp43_ = std::make_shared<LabelParam>(wParent, "日用电电量", "53.62", "Kwh", x += (w+10), y, w, h);
|
||||
|
||||
chartbar4_ = std::make_shared<ChartBarView>(wParent, QRect(10, 95, 470, 210), 5);
|
||||
chartbar4_->addItem("日用电功率");
|
||||
chartbar4_->addItem("日用电次数");
|
||||
chartbar4_->addItem("日用电电量");
|
||||
chartbar4_->updateItem(0, RANDT(7, 1, 10));
|
||||
chartbar4_->updateItem(1, RANDT(7, 1, 10));
|
||||
chartbar4_->updateItem(2, RANDT(7, 1, 10));
|
||||
}
|
||||
{
|
||||
panel5_ = std::make_shared<Panel>(this, QRect(1420, 320, 490, 300), "充电设备");
|
||||
QWidget* wParent = panel5_.get();
|
||||
|
||||
int x = 10; int y = 40;
|
||||
int w = 225; int h = 50;
|
||||
labp51_ = std::make_shared<LabelParam>(wParent, "日时间利用率", "58", "%", x, y, w, h);
|
||||
labp52_ = std::make_shared<LabelParam>(wParent, "日功率利用率", "61", "%", x += (w+20), y, w, h);
|
||||
chartbar5_ = std::make_shared<ChartBarView>(wParent, QRect(10, 95, 470, 210), 5);
|
||||
chartbar5_->addItem("日时间利用率");
|
||||
chartbar5_->addItem("日功率利用率");
|
||||
chartbar5_->updateItem(0, RANDT(7, 1, 10));
|
||||
chartbar5_->updateItem(1, RANDT(7, 1, 10));
|
||||
}
|
||||
{
|
||||
panel6_ = std::make_shared<Panel>(this, QRect(1420, 630, 490, 300), "告警信息");
|
||||
QWidget* wParent = panel6_.get();
|
||||
|
||||
int x = 10; int y = 40;
|
||||
int w = 150; int h = 50;
|
||||
labp61_ = std::make_shared<LabelParam>(wParent, "日光伏设备告警", "5", "次", x, y, w, h);
|
||||
labp62_ = std::make_shared<LabelParam>(wParent, "日储能设备告警", "2", "次", x += (w+10), y, w, h);
|
||||
labp63_ = std::make_shared<LabelParam>(wParent, "日负荷设备告警", "3", "次", x += (w+10), y, w, h);
|
||||
|
||||
chartbar6_ = std::make_shared<ChartBarView>(wParent, QRect(10, 95, 470, 210), 5);
|
||||
chartbar6_->addItem("光伏设备");
|
||||
chartbar6_->addItem("储能设备");
|
||||
chartbar6_->addItem("负荷设备");
|
||||
chartbar6_->updateItem(0, RANDT(7, 1, 10));
|
||||
chartbar6_->updateItem(1, RANDT(7, 1, 10));
|
||||
chartbar6_->updateItem(2, RANDT(7, 1, 10));
|
||||
}
|
||||
|
||||
{
|
||||
panel7_ = std::make_shared<Panel>(this, QRect(510, 680, 900, 250), "功率与辐照度");
|
||||
QWidget* wParent = panel7_.get();
|
||||
|
||||
chartline7_ = std::make_shared<ChartLineView>(wParent, QRect(10, 50, 880, 200));
|
||||
chartline7_->addItem("功率");
|
||||
chartline7_->addItem("辐照度");
|
||||
chartline7_->setAxisYLeft(-1, 1, 5);
|
||||
|
||||
double t0 = TimeUtils::datetime2tms(TimeUtils::now_date() + " 00:00:00");
|
||||
double tx = t0;
|
||||
int n = 360;
|
||||
std::vector<std::pair<double, double>> vd0(n+1);
|
||||
std::vector<std::pair<double, double>> vd1(n+1);
|
||||
for (int i = 0; i<=n; i++)
|
||||
{
|
||||
tx = t0 + i*(86400/n)*1000;
|
||||
vd0[i] = {tx, sin(2*3.1415926*float(i*2)/float(360))};
|
||||
vd1[i] = {tx, cos(2*3.1415926*float(i*2)/float(360))};
|
||||
}
|
||||
chartline7_->setAxisX(t0, tx, 13, "hh:mm");
|
||||
chartline7_->updateItem(0, vd0);
|
||||
chartline7_->updateItem(1, vd1);
|
||||
}
|
||||
|
||||
{
|
||||
wWebView = std::make_shared<QWebEngineView>(this);
|
||||
wWebView->setGeometry(510, 100, 900, 560);
|
||||
// 默认设置透明, 解决加载时的白屏闪烁
|
||||
wWebView->page()->setBackgroundColor(Qt::transparent);
|
||||
|
||||
wWebView->setContextMenuPolicy(Qt::NoContextMenu);
|
||||
//webEngineView.load(QUrl("https://www.baidu.com"));
|
||||
wWebView->load(QUrl("file:///assets/echarts/HTML/maptest.html"));
|
||||
|
||||
//connect(wWebView.get(), &QWebEngineView::loadFinished, this, &WidgetPageHome::slotLoadFinished);
|
||||
|
||||
//std::string htmlContent = "HelloWorld";
|
||||
//webEngineView.setHtml(htmlContent.c_str());
|
||||
wWebView->show();
|
||||
|
||||
//lab712_.setPixmap(QPixmap(icon.c_str()));
|
||||
|
||||
iconp1_ = std::make_shared<IconParam>(this, "光照", "27.2", "Lux", 600, 40, QColor(246, 155, 82));
|
||||
iconp2_ = std::make_shared<IconParam>(this, "风速", "1.2", "m/s", 800, 40, QColor(155, 216, 1));
|
||||
iconp3_ = std::make_shared<IconParam>(this, "环境温度", "27.2", "℃", 1000, 40, QColor(61, 254, 250));
|
||||
iconp4_ = std::make_shared<IconParam>(this, "环境湿度", "27.2", "%", 1200, 40, QColor(216, 61, 108));
|
||||
}
|
||||
}
|
||||
110
src/widgets/pages/WidgetPageOverview.h
Normal file
110
src/widgets/pages/WidgetPageOverview.h
Normal file
@@ -0,0 +1,110 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "WidgetPage.h"
|
||||
#include <QtWebEngineWidgets/QWebEngineView>
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
class LabelParam
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<QLabel> labBkg_;
|
||||
std::shared_ptr<QLabel> labKey_;
|
||||
std::shared_ptr<QLabel> labVal_;
|
||||
std::shared_ptr<QLabel> labTail_;
|
||||
|
||||
LabelParam(QWidget* parent, std::string k, std::string v, std::string t, int x, int y, int w, int h)
|
||||
{
|
||||
labBkg_ = QUI::label(parent, x, y, w, h, "", "background-color:rgba(100,100,100,50)");
|
||||
labKey_ = QUI::label(parent, x, y, w, h*0.5, k, "color:white;font: bold 16px;");
|
||||
labVal_ = QUI::label(parent, x, y+h*0.5, w*float(2.0/3.0), h*0.5, v, "color:rgb(77, 215, 240);font:bold 16px;");
|
||||
labTail_ = QUI::label(parent, x+w*float(2.0/3.0)+5, y+h*0.5, w*float(1.0/3.0), h*0.5, t, "color:white;font: bold 12px;");
|
||||
|
||||
labKey_->setAlignment(Qt::AlignCenter);
|
||||
labVal_->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
labTail_->setAlignment(Qt::AlignVCenter);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class IconParam
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<QLabel> lab711_;
|
||||
std::shared_ptr<QLabel> lab712_;
|
||||
std::shared_ptr<QLabel> lab713_;
|
||||
std::shared_ptr<QLabel> lab714_;
|
||||
|
||||
std::string tail;
|
||||
|
||||
IconParam(QWidget* parent, std::string k, std::string v, std::string t, int x, int y, QColor color= QColor(61, 254, 250))
|
||||
{
|
||||
tail = t;
|
||||
std::stringstream ss;
|
||||
ss << color.red() << "," << color.green() << "," << color.blue();
|
||||
lab711_ = QUI::label(parent, x, y, 5, 50, "", "background-color:rgb(" + ss.str() + ")");
|
||||
lab712_ = QUI::label(parent, x + 10, y, 50, 50, "", "background-color:rgba(" + ss.str() + ",50)");
|
||||
lab713_ = QUI::label(parent, x + 10 + 60, y, 100, 25, k, "font: normal 16px; color:white");
|
||||
lab714_ = QUI::label(parent, x + 10 + 60, y+25, 100, 25, v+tail, "font: normal 16px; color:white");
|
||||
}
|
||||
};
|
||||
|
||||
class WidgetPageOverview : public WidgetPage
|
||||
{
|
||||
public:
|
||||
WidgetPageOverview(QWidget* parent);
|
||||
|
||||
std::shared_ptr<Panel> panel1_;
|
||||
std::shared_ptr<QLabel> labBkg_;
|
||||
std::shared_ptr<QLabel> labDaysK_;
|
||||
std::shared_ptr<QLabel> labDaysV_;
|
||||
std::shared_ptr<QLabel> labDaysT_;
|
||||
|
||||
std::shared_ptr<LabelParam> labp1_;
|
||||
std::shared_ptr<LabelParam> labp2_;
|
||||
std::shared_ptr<LabelParam> labp3_;
|
||||
std::shared_ptr<LabelParam> labp4_;
|
||||
std::shared_ptr<LabelParam> labp5_;
|
||||
std::shared_ptr<LabelParam> labp6_;
|
||||
|
||||
|
||||
std::shared_ptr<Panel> panel2_;
|
||||
std::shared_ptr<LabelParam> labp21_;
|
||||
std::shared_ptr<LabelParam> labp22_;
|
||||
std::shared_ptr<LabelParam> labp23_;
|
||||
std::shared_ptr<ChartBarView> chartbar2_;
|
||||
|
||||
std::shared_ptr<Panel> panel3_;
|
||||
std::shared_ptr<LabelParam> labp31_;
|
||||
std::shared_ptr<LabelParam> labp32_;
|
||||
std::shared_ptr<ChartBarView> chartbar3_;
|
||||
|
||||
std::shared_ptr<Panel> panel4_;
|
||||
std::shared_ptr<LabelParam> labp41_;
|
||||
std::shared_ptr<LabelParam> labp42_;
|
||||
std::shared_ptr<LabelParam> labp43_;
|
||||
std::shared_ptr<ChartBarView> chartbar4_;
|
||||
|
||||
std::shared_ptr<Panel> panel5_;
|
||||
std::shared_ptr<LabelParam> labp51_;
|
||||
std::shared_ptr<LabelParam> labp52_;
|
||||
std::shared_ptr<ChartBarView> chartbar5_;
|
||||
|
||||
std::shared_ptr<Panel> panel6_;
|
||||
std::shared_ptr<LabelParam> labp61_;
|
||||
std::shared_ptr<LabelParam> labp62_;
|
||||
std::shared_ptr<LabelParam> labp63_;
|
||||
std::shared_ptr<ChartBarView> chartbar6_;
|
||||
|
||||
std::shared_ptr<Panel> panel7_;
|
||||
std::shared_ptr<ChartLineView> chartline7_;
|
||||
|
||||
std::shared_ptr<QWebEngineView> wWebView = nullptr;
|
||||
|
||||
std::shared_ptr<IconParam> iconp1_;
|
||||
std::shared_ptr<IconParam> iconp2_;
|
||||
std::shared_ptr<IconParam> iconp3_;
|
||||
std::shared_ptr<IconParam> iconp4_;
|
||||
|
||||
};
|
||||
359
src/widgets/pages/WidgetPageRunning.cpp
Normal file
359
src/widgets/pages/WidgetPageRunning.cpp
Normal file
@@ -0,0 +1,359 @@
|
||||
#include "WidgetPageRunning.h"
|
||||
#include "common/Logger.h"
|
||||
|
||||
static void ReviseQueuePos(int i, int maxCol, int w, int h, int& x, int& y)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
if (i%maxCol == 0)
|
||||
{
|
||||
x = 0;
|
||||
y += (h);
|
||||
}
|
||||
else
|
||||
{
|
||||
x += (w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class PanelCard : public Panel
|
||||
{
|
||||
public:
|
||||
QLabel labIcon_;
|
||||
QLabel labName_;
|
||||
QLabel labTyle_;
|
||||
QLabel labStatus_;
|
||||
std::map<std::string, std::pair<std::shared_ptr<QLabel>, std::shared_ptr<QLabel>>> mapLabParams_;
|
||||
|
||||
std::string styLabelK_ = "QLabel {font:bold 15px;color:rgb(166, 184, 221);}";
|
||||
std::string styLabel_ = "QLabel {font:bold 15px;color:white;}";
|
||||
|
||||
PanelCard(QWidget* parent, QRect rt, std::string type) : Panel(parent, rt, "")
|
||||
{
|
||||
//this->setObjectName("MyPanel");
|
||||
//std::string sty = "#MyPanel {background-color:rgb(8, 54, 91);border:1px solid rgba(255,255,255,10);border-radius:15px;}";
|
||||
this->setAutoFillBackground(true);
|
||||
//this->setStyleSheet(sty.c_str());
|
||||
this->setBackground(QColor(8, 54, 91), "border:1px solid rgba(255,255,255,10);border-radius:15px;");
|
||||
|
||||
QUI::labelImage(labIcon_, this, 10, 20, 64, 64, "assets/ui/solarPanel.png");
|
||||
QUI::label(labName_, this, 90, 20, 120, 20, "#NAME", styLabel_);
|
||||
QUI::label(labStatus_, this, 90, 40, 120, 20, "#STATUS", styLabel_);
|
||||
QUI::label(labTyle_, this, 90, 60, 120, 20, type, "QLabel {font:bold 15px;color:rgb(8, 165, 255);}");
|
||||
}
|
||||
|
||||
void setIcon(std::string icon)
|
||||
{
|
||||
labIcon_.setPixmap(QPixmap(icon.c_str()));
|
||||
}
|
||||
void setName(std::string name)
|
||||
{
|
||||
labName_.setText(name.c_str());
|
||||
}
|
||||
void setStatus(int status)
|
||||
{
|
||||
std::vector<std::string> VEC_STATUS = {"运行", "空闲", "离线", "故障"};
|
||||
if (status >=0 && status <=3)
|
||||
{
|
||||
labStatus_.setText(VEC_STATUS[status].c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
labStatus_.setText("#STATUS");
|
||||
}
|
||||
}
|
||||
void setParam(std::string k, std::string v)
|
||||
{
|
||||
std::shared_ptr<QLabel> labK = nullptr;
|
||||
std::shared_ptr<QLabel> labV = nullptr;
|
||||
|
||||
auto iter = mapLabParams_.find(k);
|
||||
if (iter == mapLabParams_.end())
|
||||
{
|
||||
int y = 100 + mapLabParams_.size() * 24;
|
||||
labK = QUI::label(this, 20, y, 80, 20, k + ":", styLabelK_);
|
||||
labV = QUI::label(this, 110, y, 120, 20, v, styLabel_);
|
||||
mapLabParams_[k] = {labK, labV};
|
||||
}
|
||||
else
|
||||
{
|
||||
labV = iter->second.second;
|
||||
labV->setText(v.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
virtual void enterEvent(QEvent* e) override
|
||||
{
|
||||
this->setBackground(QColor(30, 100, 100, 120), "border: 1px solid white;border-radius:15px;");
|
||||
}
|
||||
virtual void leaveEvent(QEvent* e) override
|
||||
{
|
||||
this->setBackground(QColor(8, 54, 91), "border:1px solid rgba(255,255,255,10);border-radius:15px;");
|
||||
}
|
||||
};
|
||||
|
||||
class PanelDeviceDetail : public Panel
|
||||
{
|
||||
public:
|
||||
PanelDeviceDetail(QWidget* parent, QRect rt) : Panel(parent, rt)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class PanelDeviceWind : public PanelDeviceDetail
|
||||
{
|
||||
public:
|
||||
std::vector<std::shared_ptr<PanelCard>> vecCards_;
|
||||
|
||||
PanelDeviceWind(QWidget* parent, QRect rt) : PanelDeviceDetail(parent, rt)
|
||||
{
|
||||
int col = 5;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int W = 280;
|
||||
int H = 320;
|
||||
for (int i = 0; i<col; i++)
|
||||
{
|
||||
ReviseQueuePos(i, 5, W+10, H+10, x, y);
|
||||
auto card = std::make_shared<PanelCard>(this, QRect(x+10, y+10, W, H), "风机");
|
||||
card->setIcon("assets/ui/icon1.png");
|
||||
card->setName("风电设备-" + std::to_string(i+1));
|
||||
card->setStatus(0);
|
||||
vecCards_.push_back(card);
|
||||
|
||||
card->setParam("位置", "能源站xxxx-xxx");
|
||||
card->setParam("工作状态", "发电/空闲");
|
||||
card->setParam("在线状态", "在线/离线");
|
||||
card->setParam("故障状态", "正常/故障");
|
||||
card->setParam("电压", "220 V");
|
||||
card->setParam("电流", "50 A");
|
||||
card->setParam("额定功率", "30 KW");
|
||||
card->setParam("实时功率", "28 KW");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class PanelDeviceSolar : public PanelDeviceDetail
|
||||
{
|
||||
public:
|
||||
std::vector<std::shared_ptr<PanelCard>> vecCards_;
|
||||
|
||||
PanelDeviceSolar(QWidget* parent, QRect rt) : PanelDeviceDetail(parent, rt)
|
||||
{
|
||||
int col = 5;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int W = 280;
|
||||
int H = 320;
|
||||
for (int i = 0; i<col; i++)
|
||||
{
|
||||
ReviseQueuePos(i, 5, W+10, H+10, x, y);
|
||||
std::string type = (i==0) ? "逆变器" : (i==1 ? "汇流箱" : "光伏板");
|
||||
auto card = std::make_shared<PanelCard>(this, QRect(x+10, y+10, W, H), type);
|
||||
card->setIcon("assets/ui/solarPanel.png");
|
||||
card->setName("设备-" + std::to_string(i+1));
|
||||
card->setStatus(0);
|
||||
vecCards_.push_back(card);
|
||||
card->setParam("位置", "能源站xxxx-xxx");
|
||||
card->setParam("电压", "220V");
|
||||
card->setParam("电流", "0.5A");
|
||||
card->setParam("额定功率", "22kw");
|
||||
card->setParam("实时功率", "6.83kw");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class PanelDeviceEnergyStorage : public PanelDeviceDetail
|
||||
{
|
||||
public:
|
||||
std::vector<std::shared_ptr<PanelCard>> vecCards_;
|
||||
|
||||
PanelDeviceEnergyStorage(QWidget* parent, QRect rt) : PanelDeviceDetail(parent, rt)
|
||||
{
|
||||
int col = 10;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int W = 280;
|
||||
int H = 320;
|
||||
for (int i = 0; i<col; i++)
|
||||
{
|
||||
ReviseQueuePos(i, 5, W+10, H+10, x, y);
|
||||
auto card = std::make_shared<PanelCard>(this, QRect(x+10, y+10, W, H), "储能电池");
|
||||
card->setIcon("assets/ui/energyStorage.png");
|
||||
card->setName("储能设备-" + std::to_string(i+1));
|
||||
card->setStatus(0);
|
||||
vecCards_.push_back(card);
|
||||
card->setParam("位置", "能源站xxxx-xxx");
|
||||
card->setParam("电压", "220V");
|
||||
card->setParam("电流", "0.5A");
|
||||
card->setParam("额定功率", "22kw");
|
||||
card->setParam("实时功率", "6.83kw");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class PanelDeviceCharge : public PanelDeviceDetail
|
||||
{
|
||||
public:
|
||||
std::vector<std::shared_ptr<PanelCard>> vecCards_;
|
||||
|
||||
PanelDeviceCharge(QWidget* parent, QRect rt) : PanelDeviceDetail(parent, rt)
|
||||
{
|
||||
int col = 5;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int W = 280;
|
||||
int H = 320;
|
||||
for (int i = 0; i<col; i++)
|
||||
{
|
||||
ReviseQueuePos(i, 5, W+10, H+10, x, y);
|
||||
auto card = std::make_shared<PanelCard>(this, QRect(x+10, y+10, W, H), "充电机");
|
||||
card->setIcon("assets/ui/charger.png");
|
||||
card->setName("充电设备-" + std::to_string(i+1));
|
||||
card->setStatus(0);
|
||||
vecCards_.push_back(card);
|
||||
card->setParam("位置", "能源站xxxx-xxx");
|
||||
card->setParam("电压", "220V");
|
||||
card->setParam("电流", "0.5A");
|
||||
card->setParam("额定功率", "22kw");
|
||||
card->setParam("实时功率", "6.83kw");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class PanelCardCamera
|
||||
{
|
||||
public:
|
||||
Panel panel_;
|
||||
QLabel labName_;
|
||||
QLabel labVideo_;
|
||||
|
||||
PanelCardCamera(QWidget* parent, QRect rt, std::string type) : panel_(parent, rt, "")
|
||||
{
|
||||
panel_.setObjectName("MyPanel");
|
||||
std::string sty = "#MyPanel {background-color:rgb(8, 54, 91);border:1px solid rgba(255,255,255,10);border-radius:15px;}";
|
||||
panel_.setAutoFillBackground(true);
|
||||
panel_.setStyleSheet(sty.c_str());
|
||||
|
||||
QUI::label(labName_, &panel_, 10, 10, rt.width()-20, 30, "xxx监控点", "font:bold 16px; color:white;");
|
||||
QUI::labelImage(labVideo_, &panel_, 10, 40, rt.width()-20, rt.height()-50, "assets/ui/camera.png");
|
||||
}
|
||||
};
|
||||
|
||||
class PanelDeviceSecurity : public PanelDeviceDetail
|
||||
{
|
||||
public:
|
||||
std::vector<std::shared_ptr<PanelCardCamera>> vecCards_;
|
||||
|
||||
PanelDeviceSecurity(QWidget* parent, QRect rt) : PanelDeviceDetail(parent, rt)
|
||||
{
|
||||
int col = 6;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int W = 410;
|
||||
int H = 308;
|
||||
for (int i = 0; i<col; i++)
|
||||
{
|
||||
ReviseQueuePos(i, 3, W+50, H+50, x, y);
|
||||
auto card = std::make_shared<PanelCardCamera>(this, QRect(x+50, y+50, W, H), "");
|
||||
vecCards_.push_back(card);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static PanelDevice* g_activePanel_ = nullptr;
|
||||
class PanelDevice : public Panel
|
||||
{
|
||||
public:
|
||||
PanelDevice(QWidget* parent, QRect rt, std::string title) : Panel(parent, rt, title)
|
||||
{
|
||||
this->setBackground(QColor(29,54,102), "border:0px solid white; border-radius:5px;");
|
||||
}
|
||||
void setBackgroundStatus(int flag)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
this->setBackground(QColor(29, 100, 102), "border: 1px solid white;");
|
||||
}
|
||||
else
|
||||
{
|
||||
this->setBackground(QColor(29, 54, 102), "border:0px solid white; border-radius:5px;");
|
||||
}
|
||||
}
|
||||
void setActive(bool flag)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
g_activePanel_ = this;
|
||||
}
|
||||
setBackgroundStatus(flag);
|
||||
if (panelDetail_)
|
||||
{
|
||||
panelDetail_->setVisible(flag);
|
||||
}
|
||||
}
|
||||
virtual void enterEvent(QEvent* e) override
|
||||
{
|
||||
setBackgroundStatus(1);
|
||||
}
|
||||
virtual void leaveEvent(QEvent* e) override
|
||||
{
|
||||
if (g_activePanel_ != this)
|
||||
{
|
||||
setBackgroundStatus(0);
|
||||
}
|
||||
}
|
||||
void mousePressEvent(QMouseEvent* e) override
|
||||
{
|
||||
if (e->button() == Qt::LeftButton)
|
||||
{
|
||||
if (g_activePanel_ != this)
|
||||
{
|
||||
if (g_activePanel_) { g_activePanel_->setActive(false); }
|
||||
this->setActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setDetailPanel(std::shared_ptr<PanelDeviceDetail> panelDetail)
|
||||
{
|
||||
panelDetail_ = panelDetail;
|
||||
}
|
||||
|
||||
std::shared_ptr<PanelDeviceDetail> panelDetail_ = nullptr;
|
||||
};
|
||||
|
||||
WidgetPageRunning::WidgetPageRunning(QWidget* parent) : WidgetPage(parent)
|
||||
{
|
||||
// 设备类型Panel
|
||||
int H = 180;
|
||||
int i = 0;
|
||||
|
||||
//panel1_ = std::make_shared<PanelDevice>(this, QRect(10, 10+H*0, 380, H-10), "风电设备");
|
||||
//panel1_->setDetailPanel(std::make_shared<PanelDeviceWind>(this, QRect(400, 10, 1490, 900)));
|
||||
//panel1_->setActive(true);
|
||||
|
||||
panel2_ = std::make_shared<PanelDevice>(this, QRect(10, 10+H*(i++), 380, H-10), "光伏设备");
|
||||
panel2_->setDetailPanel(std::make_shared<PanelDeviceSolar>(this, QRect(400, 10, 1490, 900)));
|
||||
panel2_->setActive(false);
|
||||
|
||||
panel3_ = std::make_shared<PanelDevice>(this, QRect(10, 10+H*(i++), 380, H-10), "储能设备");
|
||||
panel3_->setDetailPanel(std::make_shared<PanelDeviceEnergyStorage>(this, QRect(400, 10, 1490, 900)));
|
||||
panel3_->setActive(false);
|
||||
|
||||
panel4_ = std::make_shared<PanelDevice>(this, QRect(10, 10+H*(i++), 380, H-10), "充电设备");
|
||||
panel4_->setDetailPanel(std::make_shared<PanelDeviceCharge>(this, QRect(400, 10, 1490, 900)));
|
||||
panel4_->setActive(false);
|
||||
|
||||
panel5_ = std::make_shared<PanelDevice>(this, QRect(10, 10+H*(i++), 380, H-10), "安防设备");
|
||||
panel5_->setDetailPanel(std::make_shared<PanelDeviceSecurity>(this, QRect(400, 10, 1490, 900)));
|
||||
panel5_->setActive(false);
|
||||
|
||||
panel2_->setActive(true);
|
||||
|
||||
//panelDevice_ = std::make_shared<Panel>(this, QRect(420, 10, 1490, 900), "");
|
||||
//{
|
||||
//}
|
||||
}
|
||||
23
src/widgets/pages/WidgetPageRunning.h
Normal file
23
src/widgets/pages/WidgetPageRunning.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "WidgetPage.h"
|
||||
|
||||
class PanelDevice;
|
||||
class PanelDeviceDetail;
|
||||
|
||||
class WidgetPageRunning : public WidgetPage
|
||||
{
|
||||
public:
|
||||
WidgetPageRunning(QWidget* parent);
|
||||
|
||||
std::shared_ptr<PanelDevice> panel1_;
|
||||
std::shared_ptr<PanelDevice> panel2_;
|
||||
std::shared_ptr<PanelDevice> panel3_;
|
||||
std::shared_ptr<PanelDevice> panel4_;
|
||||
std::shared_ptr<PanelDevice> panel5_;
|
||||
|
||||
std::shared_ptr<Panel> panelDevice_;
|
||||
|
||||
std::shared_ptr<PanelDeviceDetail> panelDeviceDetial_;
|
||||
|
||||
};
|
||||
54
src/widgets/pages/WidgetPageWeb.cpp
Normal file
54
src/widgets/pages/WidgetPageWeb.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "WidgetPageWeb.h"
|
||||
#include <iostream>
|
||||
|
||||
WidgetPageWeb::WidgetPageWeb(QWidget* parent, std::string name) : WidgetPage(parent)
|
||||
{
|
||||
wWebView = std::make_shared<QWebEngineView>(this);
|
||||
wWebView->setGeometry(0, 0, 1920, 900);
|
||||
|
||||
jsHandler = new JsHandler();
|
||||
|
||||
webChannel = new QWebChannel();
|
||||
// 注册C++对象到QWebChannel,这样远端的QWebChannel也会生成一个对应的JS对象
|
||||
// 在JS中引入 qwebchannel.js, 使用 channel.objects.webNative 获取注册的“webNative”
|
||||
webChannel->registerObject("webNative", jsHandler);
|
||||
wWebView->page()->setWebChannel(webChannel);
|
||||
wWebView->setContextMenuPolicy(Qt::NoContextMenu);
|
||||
//webEngineView.load(QUrl("https://www.baidu.com"));
|
||||
|
||||
std::string url = "file:///assets/html/" + name + "/index.html";
|
||||
|
||||
std::cout << "===> url=" << url << std::endl;
|
||||
wWebView->load(QUrl(url.c_str()));
|
||||
|
||||
// 默认设置透明,解决加载过程中白屏
|
||||
wWebView->page()->setBackgroundColor(Qt::transparent);
|
||||
|
||||
// 加载进度
|
||||
connect(wWebView.get(), &QWebEngineView::loadProgress, [=](int progress)
|
||||
{
|
||||
//pWebEngineView->page()->setBackgroundColor(Qt::transparent);
|
||||
});
|
||||
|
||||
|
||||
connect(wWebView.get(), &QWebEngineView::loadFinished, this, &WidgetPageWeb::slotLoadFinished);
|
||||
connect(jsHandler, &JsHandler::signalShowWebView, this, &WidgetPageWeb::slotShowWebView);
|
||||
|
||||
//std::string htmlContent = "HelloWorld";
|
||||
//webEngineView.setHtml(htmlContent.c_str());
|
||||
wWebView->hide();
|
||||
|
||||
//webView = std::make_shared<WidgetWeb>(this);
|
||||
}
|
||||
|
||||
void WidgetPageWeb::slotLoadFinished(bool isOk)
|
||||
{
|
||||
//QString jsCode = QString("showalert('%1')").arg("Hello QtWebEngine!");
|
||||
//wWebView->page()->runJavaScript(jsCode, [](const QVariant& v) { qDebug() << v.toString(); });
|
||||
wWebView->show();
|
||||
}
|
||||
|
||||
void WidgetPageWeb::slotShowWebView()
|
||||
{
|
||||
wWebView->show();
|
||||
}
|
||||
57
src/widgets/pages/WidgetPageWeb.h
Normal file
57
src/widgets/pages/WidgetPageWeb.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
|
||||
#include "WidgetPage.h"
|
||||
|
||||
#include <QWebChannel>
|
||||
#include <QtWebEngineWidgets/QWebEngineView>
|
||||
|
||||
|
||||
class JsHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
//Q_PROPERTY(QString nativeText READ nativeText MEMBER m_nativeText NOTIFY signalNativeTextChanged FINAL)
|
||||
explicit JsHandler(QObject* parent = nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
QString nativeText() const { return m_nativeText; }
|
||||
|
||||
signals:
|
||||
//在C++中定义的信号,可以在JS端监听此信号接收消息
|
||||
void signalNativeTextChanged(const QString& text);
|
||||
void signalShowWebView();
|
||||
|
||||
public slots:
|
||||
void showWebView()
|
||||
{
|
||||
emit signalShowWebView();
|
||||
}
|
||||
|
||||
//C++ 端的公共槽函数,可以在JS端调用。
|
||||
void setNativeText(const QString& text)
|
||||
{
|
||||
m_nativeText = text;
|
||||
qDebug() << QString("run JS call CPP: setNativeText:") << text;
|
||||
emit signalNativeTextChanged("HelloWorld");
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_nativeText;
|
||||
};
|
||||
|
||||
|
||||
class WidgetPageWeb : public WidgetPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WidgetPageWeb(QWidget* parent, std::string name);
|
||||
|
||||
void slotLoadFinished(bool isOk);
|
||||
void slotShowWebView();
|
||||
|
||||
public:
|
||||
std::shared_ptr<QWebEngineView> wWebView = nullptr;
|
||||
QWebChannel* webChannel = nullptr;
|
||||
JsHandler* jsHandler = nullptr;
|
||||
};
|
||||
845
src/widgets/uihelper.cpp
Normal file
845
src/widgets/uihelper.cpp
Normal file
@@ -0,0 +1,845 @@
|
||||
#include "uihelper.h"
|
||||
|
||||
static QFont g_font("微软雅黑", 10);
|
||||
|
||||
std::string UiStyle::BTN =
|
||||
"QPushButton{background-color:rgba(150,150,150,80);border-radius:5px;font:bold 16px;color:white;border:2px solid gray;}"
|
||||
"QPushButton:hover{background-color:rgba(150,150,150,100);border:2px solid white;}"
|
||||
"QPushButton:pressed{border-width:3px 0 0 3px;border-style:inset;color:white;}";
|
||||
|
||||
std::shared_ptr<QLabel> QUI::label(QWidget* parent, int x, int y, int w, int h, std::string text, std::string sty)
|
||||
{
|
||||
auto lab = std::make_shared<QLabel>(parent);
|
||||
lab->setGeometry(x, y, w, h);
|
||||
lab->setText(text.c_str());
|
||||
lab->setFont(g_font);
|
||||
if (!sty.empty())
|
||||
{
|
||||
lab->setStyleSheet(sty.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
lab->setStyleSheet("QLabel {color:white;}");
|
||||
}
|
||||
return lab;
|
||||
}
|
||||
|
||||
void QUI::label(QLabel& lab, QWidget* parent, int x, int y, int w, int h, std::string text, std::string sty)
|
||||
{
|
||||
lab.setParent(parent);
|
||||
lab.setGeometry(x, y, w, h);
|
||||
lab.setText(text.c_str());
|
||||
lab.setFont(g_font);
|
||||
if (!sty.empty())
|
||||
{
|
||||
lab.setStyleSheet(sty.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
lab.setStyleSheet("QLabel {color:white;}");
|
||||
}
|
||||
}
|
||||
|
||||
void QUI::labelImage(QLabel& lab, QWidget* parent, int x, int y, int w, int h, std::string img)
|
||||
{
|
||||
lab.setParent(parent);
|
||||
lab.setGeometry(x, y, w, h);
|
||||
lab.setPixmap(QPixmap(img.c_str()));
|
||||
}
|
||||
|
||||
std::shared_ptr<LabelPairH> QUI::labelPair(QWidget* parent, int x, int y, int w, int h, int w1, std::string k, std::string v)
|
||||
{
|
||||
return std::make_shared<LabelPairH>(parent, QRect(x, y, w, h), w1, k, v);
|
||||
}
|
||||
|
||||
std::shared_ptr<LabelPairV> QUI::labelPairV(QWidget* parent, int x, int y, int w, int h, int h1, std::string k, std::string v)
|
||||
{
|
||||
auto labPair = std::make_shared<LabelPairV>(parent, QRect(x, y, w, h), h1, k, v);
|
||||
const std::string STY_VAL = "font:bold 18px;color:rgb(38,220,172);";
|
||||
labPair->setValStyle(STY_VAL);
|
||||
return labPair;
|
||||
}
|
||||
|
||||
void QUI::button(QPushButton& btn, QWidget* parent, int x, int y, int w, int h, std::string text, std::string sty)
|
||||
{
|
||||
btn.setParent(parent);
|
||||
btn.setGeometry(x, y, w, h);
|
||||
btn.setText(text.c_str());
|
||||
btn.setFont(g_font);
|
||||
if (!sty.empty())
|
||||
{
|
||||
btn.setStyleSheet(sty.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
QPushButton* QUI::button(QWidget* parent, int x, int y, int w, int h, std::string text, std::string sty/* = ""*/)
|
||||
{
|
||||
QPushButton* btn = new QPushButton(parent);
|
||||
btn->setGeometry(x, y, w, h);
|
||||
btn->setText(text.c_str());
|
||||
btn->setFont(g_font);
|
||||
if (!sty.empty())
|
||||
{
|
||||
btn->setStyleSheet(sty.c_str());
|
||||
}
|
||||
return btn;
|
||||
}
|
||||
|
||||
//std::shared_ptr<QComboBox> QUI::combox(QWidget* parent, int x, int y, int w, int h, std::vector<std::string>& items)
|
||||
//{
|
||||
// std::shared_ptr<QComboBox> comb = std::make_shared<QComboBox>(parent);
|
||||
// comb->setGeometry(x, y, w, h);
|
||||
// QStringList strlist;
|
||||
// for (auto& s: items)
|
||||
// {
|
||||
// strlist << s.c_str();
|
||||
// }
|
||||
// comb->insertItems(0, strlist);
|
||||
// return comb;
|
||||
//}
|
||||
|
||||
void QUI::combox(QComboBox& comb, QWidget* parent, int x, int y, int w, int h, std::vector<std::string> items, std::string v/* = ""*/)
|
||||
{
|
||||
comb.setParent(parent);
|
||||
comb.setGeometry(x, y, w, h);
|
||||
QStringList strlist;
|
||||
for (auto& s: items)
|
||||
{
|
||||
strlist << s.c_str();
|
||||
}
|
||||
comb.insertItems(0, strlist);
|
||||
if (!v.empty())
|
||||
{
|
||||
comb.setCurrentText(v.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void QUI::lineedit(QLineEdit& line, QWidget* parent, int x, int y, int w, int h)
|
||||
{
|
||||
line.setParent(parent);
|
||||
line.setGeometry(x, y, w, h);
|
||||
}
|
||||
|
||||
void QUI::setBackground(QWidget* w, std::string name, QColor color, std::string border)
|
||||
{
|
||||
if (!w) { return; }
|
||||
w->setObjectName(name.c_str());
|
||||
std::string sty = "#" + name + "{background-color:rgba("
|
||||
+ std::to_string(color.red())
|
||||
+ "," + std::to_string(color.green())
|
||||
+ "," + std::to_string(color.blue())
|
||||
+ "," + std::to_string(color.alpha())
|
||||
+ ");" + border + "}";
|
||||
w->setAutoFillBackground(true);
|
||||
w->setStyleSheet(sty.c_str());
|
||||
}
|
||||
|
||||
Panel::Panel(QWidget* parent, QRect rt, std::string title) : QWidget(parent)
|
||||
{
|
||||
this->setGeometry(rt);
|
||||
|
||||
// 设置背景色:方法一
|
||||
//QPalette palette(this->palette());
|
||||
//palette.setColor(QPalette::Background, QColor(29, 54, 102)); // 设置背景色
|
||||
//this->setAutoFillBackground(true);
|
||||
//this->setPalette(palette);
|
||||
|
||||
// 设置背景色:方法二
|
||||
//this->setObjectName("PanelBase");
|
||||
//this->setStyleSheet("#PanelBase{background-color:rgb(30,50,100);border-radius:5px;}");
|
||||
|
||||
// 设置背景色
|
||||
QUI::setBackground(this, "PanelBase", QColor(29, 54, 102, 50));
|
||||
setMouseTracking(true);
|
||||
if (!title.empty())
|
||||
{
|
||||
// 渐变
|
||||
std::string styBkg = "background-color:qlineargradient(x1:0,y1:0, x2:1,y2:0,stop:0 rgb(3,208,242),stop:0.9 rgba(3,208,242,0));";
|
||||
// background-color:rgba(3, 208, 242, 200);
|
||||
QUI::label(labBkg_, this, 10, 30, this->width()-20, 2, "", styBkg);
|
||||
QUI::label(labIcon_, this, 10, 7, 6, 16, "", "background-color:rgb(33, 255, 210);");
|
||||
QUI::label(labTitle_, this, 20, 5, this->width(), 20, title.c_str(), "color:rgb(99, 196, 216);font:bold 16px;");
|
||||
}
|
||||
|
||||
this->show();
|
||||
}
|
||||
|
||||
void Panel::setBackground(QColor color, std::string border)
|
||||
{
|
||||
QUI::setBackground(this, "PanelBase", color, border);
|
||||
}
|
||||
|
||||
ChartBarView::ChartBarView(QWidget* parent, QRect rt, int xfrag)
|
||||
: QChartView(parent)
|
||||
, xfrag_(xfrag)
|
||||
{
|
||||
QFont font("微软雅黑", 9);
|
||||
this->setGeometry(rt);
|
||||
QColor labColor(255, 255, 255);
|
||||
|
||||
QUI::label(labTitle_, this, 0, 0, this->width(), 24, "");
|
||||
labTitle_.setAlignment(Qt::AlignHCenter);
|
||||
labTitle_.setFont(QFont("微软雅黑", 12, 100));
|
||||
|
||||
this->setFont(QFont("微软雅黑", 8));
|
||||
chart_ = std::make_shared<QChart>();
|
||||
chart_->setTitleFont(font);
|
||||
chart_->setMargins(QMargins(0,0,0,0));
|
||||
//chart_->setAnimationOptions(QChart::SeriesAnimations); // 动画方式
|
||||
setChart(chart_.get());
|
||||
|
||||
// === 初始化序列 ==============================================================
|
||||
series_ = std::make_shared<QBarSeries>();
|
||||
series_->setBarWidth(0.8);
|
||||
chart_->addSeries(series_.get());
|
||||
|
||||
// === 初始化X轴 ==============================================================
|
||||
// 创建 X 轴并设置其分类标签
|
||||
QStringList ticksX;
|
||||
for (int i = 1; i <= xfrag; ++i) {
|
||||
ticksX << QString::number(i);
|
||||
}
|
||||
axisX_ = std::make_shared<QBarCategoryAxis>();
|
||||
axisX_->setLabelsColor(labColor); // 设置X轴的颜色
|
||||
axisX_->setGridLineVisible(false);
|
||||
axisX_->append(ticksX); // 将分类标签添加到 X 轴
|
||||
chart_->addAxis(axisX_.get(), Qt::AlignBottom); // 将 X 轴添加到图表底部
|
||||
series_->attachAxis(axisX_.get()); // 将柱状图系列与 X 轴关联
|
||||
|
||||
// === 初始化Y轴 ==============================================================
|
||||
axisYLeft_ = std::make_shared<QValueAxis>();
|
||||
axisYLeft_->setGridLineColor(QColor(200, 200, 200, 100));
|
||||
axisYLeft_->setTickCount(6);
|
||||
axisYLeft_->setRange(0, 10); // 设置 Y 轴的范围为 0 到 100
|
||||
chart_->addAxis(axisYLeft_.get(), Qt::AlignLeft); // 将 Y 轴添加到图表左侧
|
||||
series_->attachAxis(axisYLeft_.get()); // 将柱状图系列与 Y 轴关联
|
||||
axisYLeft_->setLabelsColor(labColor);
|
||||
|
||||
// 设置背景色
|
||||
this->setBackground(QColor(30, 50, 100, 50));
|
||||
|
||||
// === 初始化柱体 ==============================================================
|
||||
//QBarSet* set1 = new QBarSet("10/01");
|
||||
//for (int i = 1; i <= xfrag; ++i) { *set1 << i; }
|
||||
//series_->append(set1);
|
||||
//this->addBar("日换电次数1");
|
||||
//this->addBar("日换电次数2");
|
||||
//this->addBar("日换电次数3");
|
||||
//this->addBar("日换电次数4");
|
||||
|
||||
//// === 示例:更新bar的数据
|
||||
//set1->replace(0, 8);
|
||||
|
||||
//// === 示例:更新X轴
|
||||
//QStringList ticksX2;
|
||||
//for (int i = 1; i <= xfrag; ++i) {
|
||||
// ticksX2 << QString::number(100+i);
|
||||
//}
|
||||
//axisX_->setCategories(ticksX2);
|
||||
|
||||
chart_->axisX()->setLabelsFont(font);
|
||||
chart_->axisY()->setLabelsFont(font);
|
||||
chart_->axisX()->setTitleFont(font);
|
||||
chart_->axisY()->setTitleFont(font);
|
||||
|
||||
// 设置图例在图表中的位置
|
||||
// 参数1: 水平位置
|
||||
// 参数2: 垂直位置
|
||||
// 参数3: 对齐方式
|
||||
// , Qt::HorizontalAlignment::Right, Qt::VerticalAlignment::Top
|
||||
|
||||
// 附着图表
|
||||
//chart_->legend()->attachToChart();
|
||||
//// 位于图表上方
|
||||
//chart_->legend()->setAlignment(Qt::AlignTop);
|
||||
//// 位于图表下方
|
||||
//chart_->legend()->setAlignment(Qt::AlignBottom);
|
||||
//// 位于图表左侧
|
||||
//chart_->legend()->setAlignment(Qt::AlignLeft);
|
||||
//// 位于图表右侧
|
||||
//chart_->legend()->setAlignment(Qt::AlignRight);
|
||||
//// 不附着图表
|
||||
//chart_->legend()->detachFromChart();
|
||||
chart_->legend()->setFont(g_font);
|
||||
chart_->legend()->setLabelColor(labColor);
|
||||
chart_->legend()->setAlignment(Qt::AlignTop);
|
||||
//chart_->legend()->setGeometry(QRectF(50, 0, this->width(), 24));
|
||||
//chart_->legend()->update();
|
||||
}
|
||||
|
||||
void ChartBarView::setTitle(std::string title)
|
||||
{
|
||||
//chart_->setTitle(title.c_str());
|
||||
labTitle_.setText(title.c_str());
|
||||
labTitle_.setGeometry(0, 10, this->width(), 24);
|
||||
|
||||
QMargins margin;
|
||||
margin.setTop(40);
|
||||
chart_->setMargins(margin);
|
||||
chart_->legend()->setGeometry(QRectF(50, 20, this->width(), 24));
|
||||
}
|
||||
|
||||
std::shared_ptr<QChart> ChartBarView::chart()
|
||||
{
|
||||
return chart_;
|
||||
}
|
||||
|
||||
QBarSet& ChartBarView::addItem(std::string name)
|
||||
{
|
||||
int index = series_->barSets().size();
|
||||
QBarSet* barSet = new QBarSet(name.c_str());
|
||||
//bar初始化数据
|
||||
for (int i = 1; i <= xfrag_; ++i) { *barSet << 0; }
|
||||
//// === 示例:更新bar的数据
|
||||
//barSet->replace(0, 8);
|
||||
series_->append(barSet);
|
||||
chart_->legend()->setGeometry(QRectF(50, 0, this->width(), 24));
|
||||
return *barSet;
|
||||
}
|
||||
|
||||
void ChartBarView::updateItem(int index, std::vector<double>& vd)
|
||||
{
|
||||
QBarSet* barSet = this->getBar(index);
|
||||
if (barSet)
|
||||
{
|
||||
for (int i = 0; i < xfrag_ && i< vd.size(); ++i)
|
||||
{
|
||||
barSet->replace(i, vd[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QBarSet* ChartBarView::getBar(int index)
|
||||
{
|
||||
auto lstBarSet = series_->barSets();
|
||||
if (index < lstBarSet.size())
|
||||
{
|
||||
return lstBarSet[index];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ChartBarView::setBackground(QColor& color)
|
||||
{
|
||||
//this->setAutoFillBackground(true);
|
||||
//QPalette palette;
|
||||
//palette.setColor(QPalette::Window, color); // 设置背景色
|
||||
//this->setPalette(palette);
|
||||
|
||||
QUI::setBackground(this, "ChartBarView", color);
|
||||
//this->setObjectName("ChartBarView");
|
||||
//this->setStyleSheet("#ChartBarView{background-color:rgb(29,54,102);border-radius:5px;}");
|
||||
|
||||
chart_->setBackgroundBrush(QBrush(QColor(100,100,100,0))); // 设置背景色
|
||||
chart_->setBackgroundVisible(true);
|
||||
}
|
||||
|
||||
void ChartBarView::setAxisXTick(std::vector<std::string>& vecTick)
|
||||
{
|
||||
QStringList ticks;
|
||||
for (int i = 0; i < xfrag_ && i<vecTick.size(); ++i) {
|
||||
ticks << vecTick[i].c_str();
|
||||
}
|
||||
axisX_->setCategories(ticks);
|
||||
}
|
||||
|
||||
ChartLineView::ChartLineView(QWidget* parent, QRect rt) : QChartView(parent)
|
||||
{
|
||||
QColor labColor(255, 255, 255);
|
||||
QUI::setBackground(this, "ChartLineView1", QColor(30, 50, 100, 50));
|
||||
this->setGeometry(rt);
|
||||
// 图表视图
|
||||
//QChartView* chartView = new QChartView(chart, wParent);
|
||||
|
||||
//this->setGeometry(10, 30, 900, 240);
|
||||
//this->setRenderHint(QPainter::Antialiasing); // 反锯齿绘制
|
||||
|
||||
// 图表
|
||||
chart_ = std::make_shared<QChart>();
|
||||
chart_->setBackgroundBrush(QBrush(QColor(100, 100, 100, 0))); // 设置背景色
|
||||
chart_->setBackgroundVisible(true);
|
||||
//chart_->setAnimationOptions(QChart::SeriesAnimations); // 动画方式
|
||||
//chart_->setTheme(QtCharts::QChart::ChartThemeBlueNcs); // 设置主题
|
||||
//chart_->setTitle("方位角数据"); // 设置标题
|
||||
chart_->setMargins(QMargins(0, 0, 0, 0));
|
||||
this->setChart(chart_.get());
|
||||
|
||||
QDateTime curDateTIme = QDateTime::currentDateTime();
|
||||
qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
|
||||
|
||||
// x轴(时间轴方式)
|
||||
axisX = std::make_shared<QDateTimeAxis>();
|
||||
axisX->setLabelsColor(labColor);
|
||||
//axisX->setTitleText("时间(分:秒)"); // x轴显示标题
|
||||
axisX->setGridLineVisible(false); // 隐藏背景网格X轴框线
|
||||
axisX->setFormat("hh:mm"); // x轴格式
|
||||
axisX->setLabelsAngle(0); // x轴显示的文字倾斜角度
|
||||
axisX->setTickCount(10); // 轴上点的个数
|
||||
axisX->setRange(curDateTIme, curDateTIme.addSecs(10)); // 范围
|
||||
axisX->setLabelsFont(QFont("微软雅黑", 9));
|
||||
|
||||
// y轴
|
||||
axisY = std::make_shared<QValueAxis>();
|
||||
axisY->setGridLineColor(QColor(200, 200, 200, 100));
|
||||
axisY->setLabelsColor(labColor);
|
||||
//AxisY->setTitleText("角度"); // y轴显示标题
|
||||
axisY->setRange(0, 20); // 范围
|
||||
axisY->setTickCount(6); // 轴上点的个数
|
||||
axisY->setGridLineVisible(true); // 背景网格Y轴框线
|
||||
axisY->setLabelsFont(QFont("微软雅黑", 9));
|
||||
|
||||
chart_->addAxis(axisX.get(), Qt::AlignBottom); // 设置x轴位置
|
||||
chart_->addAxis(axisY.get(), Qt::AlignLeft); // 设置y轴位置
|
||||
|
||||
// 图例
|
||||
//chart_->legend()->detachFromChart();
|
||||
chart_->legend()->setFont(g_font);
|
||||
chart_->legend()->setLabelColor(labColor);
|
||||
chart_->legend()->setVisible(true); // 图例显示
|
||||
chart_->legend()->setAlignment(Qt::AlignTop); // 图例向下居中
|
||||
}
|
||||
|
||||
void ChartLineView::addItem(std::string name)
|
||||
{
|
||||
auto series = std::make_shared< QLineSeries>();
|
||||
chart_->addSeries(series.get()); // 添加线段
|
||||
series->attachAxis(axisX.get()); // 线段依附的x轴
|
||||
series->attachAxis(axisY.get()); // 线段依附的y轴
|
||||
series->setName(name.c_str()); // 线段名称,在图例会显示
|
||||
vecSeries_.push_back(series);
|
||||
//series->setPen(QPen(Qt::red, 0.6, Qt::SolidLine)); // 设置线段pen
|
||||
}
|
||||
|
||||
//#include "common/TimeUtils.h"
|
||||
void ChartLineView::updateItem(int index, std::vector<std::pair<double, double>>& vd)
|
||||
{
|
||||
if (index >= vecSeries_.size()) { return; }
|
||||
|
||||
auto& series = vecSeries_[index];
|
||||
series->clear();
|
||||
for (int i = 0; i < vd.size(); ++i)
|
||||
{
|
||||
series->append(vd[i].first, vd[i].second);
|
||||
}
|
||||
|
||||
//int64_t t0 = TimeUtils::datetime2tms(TimeUtils::now_date() + " 00:00:00");
|
||||
//int64_t tx = t0;
|
||||
//for (int i = 0; i<=240; i++)
|
||||
//{
|
||||
// tx = t0 + (i*360)*1000;
|
||||
// series->append(tx, qrand()%18);
|
||||
//}
|
||||
//this->setAxisX(t0, tx, 13);
|
||||
//this->setAxisYLeft(0, 20, 6);
|
||||
|
||||
//QDateTime t0 = QDateTime::fromString("2024-11-28 00:00:00", "yyyy-MM-dd hh:mm:ss");
|
||||
//QDateTime tx;
|
||||
//for (int i = 0; i<=240; i++)
|
||||
//{
|
||||
// tx = t0.addSecs(i*360);
|
||||
// series->append(tx.toMSecsSinceEpoch(), qrand()%18);
|
||||
//}
|
||||
//this->setAxisX(t0.toMSecsSinceEpoch(), tx.toMSecsSinceEpoch(), 13);
|
||||
//this->setAxisYLeft(0, 20, 6);
|
||||
}
|
||||
void ChartLineView::setAxisX(double min, double max, int tickCount, std::string fmt)
|
||||
{
|
||||
axisX->setRange(QDateTime::fromMSecsSinceEpoch(min), QDateTime::fromMSecsSinceEpoch(max)); // 范围
|
||||
axisX->setTickCount(tickCount); // 轴上点的个数
|
||||
axisX->setFormat(fmt.c_str());
|
||||
}
|
||||
|
||||
void ChartLineView::setAxisYLeft(double min, double max, double tickCount, std::string fmt)
|
||||
{
|
||||
axisY->setRange(min, max);
|
||||
axisY->setTickCount(tickCount);
|
||||
axisY->setLabelFormat(fmt.c_str());
|
||||
}
|
||||
|
||||
ProgressView::ProgressView(QWidget* parent, int x, int y, int h, int w, int d, int n)
|
||||
: QWidget(parent)
|
||||
, num_(n)
|
||||
{
|
||||
this->setGeometry(x, y, (w+d)*num_+4+42, h);
|
||||
this->show();
|
||||
vecBar_.resize(num_);
|
||||
|
||||
const std::string STY_LAB = "font:bold 14px;color:white;";
|
||||
|
||||
QUI::label(labBarBkg_, this, 0, 0, width(), height(), "", "border-width:1px;border-style:solid;border-color:rgba(40,169,222,255);");
|
||||
for (int i = 0; i < num_; i++)
|
||||
{
|
||||
vecBar_[i] = QUI::label(this, 2+i*(w+d), 2, w, height() - 4, "", "background-color:rgba(255,255,255,30);");
|
||||
}
|
||||
QUI::label(labVal_, this, width()-42, 0, 40, height(), "100%", STY_LAB);
|
||||
//labVal_.setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
}
|
||||
|
||||
void ProgressView::setVal(int v)
|
||||
{
|
||||
if (v<0) { v = 0; }
|
||||
if (v>100) { v = 100; }
|
||||
labVal_.setText(QString::number(v) + "%");
|
||||
float c = float(v)*0.01;
|
||||
int index = c*float(num_) - 1;
|
||||
for (int i = 0; i<num_; i++)
|
||||
{
|
||||
int r = 0 + 255.0f*float(i)/float(num_);
|
||||
int g = 255 - 255.0f*float(i)/float(num_);
|
||||
std::string strColor = "background-color:rgba(" + std::to_string(r) + "," + std::to_string(g) + ",0,255);";
|
||||
vecBar_[i]->setStyleSheet(index>=i ? strColor.c_str() : "background-color:rgba(255,255,255,30);");
|
||||
}
|
||||
}
|
||||
|
||||
LabelPairV::LabelPairV(QWidget* parent, QRect rt, int h, std::string k, std::string v)
|
||||
{
|
||||
QUI::label(labV_, parent, rt.x(), rt.y(), rt.width(), h, v);
|
||||
QUI::label(labK_, parent, rt.x(), rt.y()+h, rt.width(), rt.height()-h, k);
|
||||
labV_.setAlignment(Qt::AlignCenter);
|
||||
labK_.setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
void LabelPairV::setVal(std::string v, std::string sty/* = ""*/)
|
||||
{
|
||||
labV_.setText(v.c_str());
|
||||
if (!sty.empty()) { labV_.setStyleSheet(sty.c_str()); }
|
||||
}
|
||||
void LabelPairV::setValStyle(std::string sty)
|
||||
{
|
||||
labV_.setStyleSheet(sty.c_str());
|
||||
}
|
||||
void LabelPairV::setKeyStyle(std::string sty)
|
||||
{
|
||||
labK_.setStyleSheet(sty.c_str());
|
||||
}
|
||||
void LabelPairV::setStyle(std::string styK, std::string styV /*= ""*/)
|
||||
{
|
||||
this->setKeyStyle(styK);
|
||||
this->setValStyle(styV);
|
||||
}
|
||||
|
||||
LabelPairH::LabelPairH(QWidget* parent, QRect rt, int w, std::string k, std::string v)
|
||||
{
|
||||
QUI::label(labK_, parent, rt.x(), rt.y(), w, rt.height(), k);
|
||||
QUI::label(labV_, parent, rt.x()+w, rt.y(), rt.width()-w, rt.height(), v);
|
||||
}
|
||||
|
||||
void LabelPairH::setVal(std::string v, std::string sty/* = ""*/)
|
||||
{
|
||||
labV_.setText(v.c_str());
|
||||
if (!sty.empty()) { labV_.setStyleSheet(sty.c_str()); }
|
||||
}
|
||||
|
||||
void LabelPairH::setValStyle(std::string sty)
|
||||
{
|
||||
labV_.setStyleSheet(sty.c_str());
|
||||
}
|
||||
|
||||
void LabelPairH::setKeyStyle(std::string sty)
|
||||
{
|
||||
labK_.setStyleSheet(sty.c_str());
|
||||
}
|
||||
void LabelPairH::setStyle(std::string styK, std::string styV /*= ""*/)
|
||||
{
|
||||
this->setKeyStyle(styK);
|
||||
this->setValStyle(styV);
|
||||
}
|
||||
|
||||
static const std::string STY_TAB_BTN = R"(
|
||||
QPushButton { background-color:rgb(240,120,0);border-radius:0px;font:bold 14px;color:white;border:1px solid #20a481; }
|
||||
QPushButton:hover { background-color:rgba(32,164,128,255);color:white; }
|
||||
QPushButton:pressed { border-width:3px 0 0 3px;border-style:inset;color:white;}
|
||||
)";
|
||||
|
||||
static const std::string STY_TAB = R"(
|
||||
QTableWidget
|
||||
{
|
||||
background-color:rgb(37, 89, 120);
|
||||
alternate-background-color:rgb(57, 103, 130);
|
||||
color:white;
|
||||
font:bold 13px;
|
||||
selection-background-color:rgba(53, 125, 203, 100);
|
||||
}
|
||||
QTableWidget::item {padding-left:0px;text-align:center;color:rgba(255,255,255,200);}
|
||||
QTableWidget::item:selected {color:#FFFFFF; background: rgba(53, 125, 203,100);}
|
||||
)";
|
||||
|
||||
|
||||
//QTableWidget::item:hover
|
||||
//{
|
||||
// color:#FFFFFF;
|
||||
// background: #4B4B4D;
|
||||
//}
|
||||
|
||||
//QHeaderView::section,QTableCornerButton:section
|
||||
//{
|
||||
// text-align:center;
|
||||
// padding:3px;
|
||||
// margin:0px;
|
||||
// color:#DCDCDC;
|
||||
// border:1px solid #242424;
|
||||
// border-left-width:0px;
|
||||
// border-right-width:1px;
|
||||
// border-top-width:0px;
|
||||
// border-bottom-width:1px;
|
||||
// background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 #646464,stop:1 #525252);
|
||||
// }
|
||||
//QHeaderView::section:selected
|
||||
//{
|
||||
// color:#FFFFFF;
|
||||
// border:1px solid #242424;
|
||||
//}
|
||||
//QScrollBar:vertical{
|
||||
// width:8px;
|
||||
// border-style:flat;
|
||||
// border-radius: 4px;
|
||||
// border:0px;
|
||||
// background: #19191A;
|
||||
//}
|
||||
//QScrollBar::handle:vertical{
|
||||
// background: rgba(255,255,255,0.50);
|
||||
// border-radius: 4px;
|
||||
// width:8px;
|
||||
// min-height:91px;
|
||||
// border-style:flat;
|
||||
//}
|
||||
//QScrollBar::handle:vertical::hover{
|
||||
// background: rgba(255,255,255,0.90);
|
||||
// border-radius: 4px;
|
||||
// width:8px;
|
||||
//}
|
||||
//QScrollBar::handle:vertical::pressed{
|
||||
// background: rgba(255,255,255,0.90);
|
||||
// border-radius:4px;
|
||||
// width:8px;
|
||||
//}
|
||||
//QScrollBar::sub-page:vertical {
|
||||
// background: #19191A;
|
||||
//border-style:flat;
|
||||
//}
|
||||
//QScrollBar::add-page:vertical {
|
||||
// background: #19191A;
|
||||
//border-style:flat;
|
||||
//}
|
||||
//QScrollBar::add-line:vertical{
|
||||
// background: #19191A;
|
||||
//}
|
||||
//QScrollBar::sub-line:vertical {
|
||||
// background: #19191A;
|
||||
//}
|
||||
//QScrollBar:horizontal{
|
||||
// height:8px;
|
||||
// border-style:flat;
|
||||
// border-radius: 4px;
|
||||
// border:0px;
|
||||
//background: #19191A;
|
||||
//}
|
||||
//QScrollBar::handle:horizontal{
|
||||
// background: rgba(255,255,255,0.50);
|
||||
// border-radius: 4px;
|
||||
// height:8px;
|
||||
// min-width:91px;
|
||||
// border-style:flat;
|
||||
//}
|
||||
//QScrollBar::handle:horizontal::hover{
|
||||
// background: rgba(255,255,255,0.90);
|
||||
// border-radius: 4px;
|
||||
// height:8px;
|
||||
//}
|
||||
//QScrollBar::handle:horizontal::pressed{
|
||||
// background: rgba(255,255,255,0.90);
|
||||
// border-radius:4px;
|
||||
// height:8px;
|
||||
//}
|
||||
//QScrollBar::sub-page:horizontal {
|
||||
// background: #19191A;
|
||||
// border-style:flat;
|
||||
//}
|
||||
//QScrollBar::add-page:horizontal {
|
||||
// background: #19191A;
|
||||
// border-style:flat;
|
||||
//}
|
||||
//QScrollBar::sub-line:horizontal {
|
||||
// background: #19191A;
|
||||
//}
|
||||
//QScrollBar::add-line:horizontal{
|
||||
// background: #19191A;
|
||||
//}
|
||||
|
||||
static const std::string STY_TAB_HEADER = R"(
|
||||
QHeaderView {background:rgb(46,53,97); font:bold 15px;}
|
||||
QHeaderView::section {background:rgb(46,53,97);color:white;border:1px solid gray;}
|
||||
)";
|
||||
|
||||
TableBase::TableBase(QWidget* parent, int rowMax, int colMax)
|
||||
{
|
||||
widget_ = std::make_shared<QTableWidget>(rowMax, colMax, parent);
|
||||
//this->setItemDelegate(new MyTableItemDelegate(this));
|
||||
|
||||
// "alternate-background-color:rgb(11,231,255);background-color:rgb(222,191,255);"
|
||||
widget_->setStyleSheet(STY_TAB.c_str());
|
||||
// 交替颜色
|
||||
widget_->setAlternatingRowColors(true);
|
||||
// 单元格编辑()
|
||||
widget_->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
// 选中一行
|
||||
widget_->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
|
||||
// === 水平表头
|
||||
auto horiHeader = widget_->horizontalHeader();
|
||||
horiHeader->setFixedHeight(40);
|
||||
horiHeader->setStyleSheet(STY_TAB_HEADER.c_str());
|
||||
|
||||
// === 垂直表头
|
||||
auto vertHeader = widget_->verticalHeader();
|
||||
// 隐藏垂直表头
|
||||
vertHeader->setVisible(false);
|
||||
// 设置默认行高
|
||||
vertHeader->setDefaultSectionSize(32);
|
||||
}
|
||||
|
||||
TableBase::~TableBase()
|
||||
{
|
||||
widget_->clearContents();
|
||||
}
|
||||
|
||||
void TableBase::setGeometry(int x, int y, int w, int h)
|
||||
{
|
||||
if (widget_)
|
||||
{
|
||||
widget_->setGeometry(x, y, w, h);
|
||||
}
|
||||
}
|
||||
|
||||
void TableBase::setHeaderH(std::vector<std::string> vecHeader)
|
||||
{
|
||||
widget_->setColumnCount(vecHeader.size());
|
||||
QStringList strList;
|
||||
for (int i = 0; i<vecHeader.size(); ++i) { strList << vecHeader[i].c_str(); }
|
||||
widget_->setHorizontalHeaderLabels(strList);
|
||||
}
|
||||
|
||||
void TableBase::setHeaderWidth(std::vector<int> vecWidth)
|
||||
{
|
||||
for (int i = 0; i<vecWidth.size(); ++i)
|
||||
{
|
||||
if (vecWidth[i] > 0)
|
||||
{
|
||||
widget_->setColumnWidth(i, vecWidth[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TableBase::setOperate(std::vector<std::string> vecOperate, std::function<void(int, std::string)> cb)
|
||||
{
|
||||
cbOper_ = cb;
|
||||
vecOperate_ = vecOperate;
|
||||
//if (vecOperate_.size() > 0)
|
||||
{
|
||||
int colCount = widget_->columnCount();
|
||||
widget_->setColumnCount(colCount + 1);
|
||||
widget_->setHorizontalHeaderItem(colCount, new QTableWidgetItem("操作"));
|
||||
widget_->horizontalHeader()->setSectionResizeMode(colCount, QHeaderView::Stretch);
|
||||
}
|
||||
}
|
||||
|
||||
void TableBase::setRowData(int row, std::vector<std::string> vd)
|
||||
{
|
||||
int rowCount = widget_->rowCount();
|
||||
if (row >= rowCount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int dataColCount = widget_->columnCount();
|
||||
if (vecOperate_.size() > 0)
|
||||
{
|
||||
dataColCount--;
|
||||
// 创建操作按钮
|
||||
if (vecWidgetOper_.size() != rowCount)
|
||||
{
|
||||
vecWidgetOper_.resize(rowCount, NULL);
|
||||
}
|
||||
std::shared_ptr<QWidget> wOpt = vecWidgetOper_[row];
|
||||
if (!wOpt)
|
||||
{
|
||||
wOpt = std::make_shared<QWidget>();
|
||||
wOpt->setMaximumSize(QSize(400, 40));
|
||||
vecWidgetOper_[row] = wOpt;
|
||||
|
||||
for (int i = 0; i<vecOperate_.size(); i++)
|
||||
{
|
||||
std::string operText = vecOperate_[i];
|
||||
QPushButton* btn = QUI::button(wOpt.get(), 5+85*i, 5, 80, 24, operText, UiStyle::BTN);
|
||||
QObject::connect(btn, &QPushButton::clicked, widget_.get(), [=]() { this->onOperate(row, operText); });
|
||||
}
|
||||
widget_->setCellWidget(row, dataColCount, wOpt.get());
|
||||
}
|
||||
}
|
||||
for (int col = 0; col<dataColCount; col++)
|
||||
{
|
||||
if (col < vd.size())
|
||||
{
|
||||
QTableWidgetItem* item = widget_->item(row, col);
|
||||
if (!item)
|
||||
{
|
||||
item = new QTableWidgetItem();
|
||||
widget_->setItem(row, col, item);
|
||||
}
|
||||
item->setText(vd[col].c_str());
|
||||
item->setTextAlignment(Qt::AlignCenter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TableBase::clear()
|
||||
{
|
||||
if (!widget_) { return; }
|
||||
widget_->clearContents();
|
||||
vecWidgetOper_.clear();
|
||||
}
|
||||
|
||||
std::shared_ptr<QTableWidget> TableBase::widget()
|
||||
{
|
||||
return widget_;
|
||||
}
|
||||
|
||||
void TableBase::onOperate(int row, std::string oper)
|
||||
{
|
||||
auto curItem = widget_->item(row, 0);
|
||||
widget_->setCurrentItem(curItem);
|
||||
|
||||
if (cbOper_) { cbOper_(row, oper); }
|
||||
|
||||
//curItem->setFlags(curItem->flags() | Qt::ItemIsEditable);
|
||||
//QPushButton* btn = qobject_cast<QPushButton*>(sender());
|
||||
//std::string text = btn->text().toStdString();
|
||||
}
|
||||
|
||||
PageCtrl::PageCtrl(QWidget* parent, QRect rt, int pageSize) : QWidget(parent), pageSize_(pageSize)
|
||||
{
|
||||
this->setGeometry(rt);
|
||||
QUI::setBackground(this, "PageCtrl", QColor(255, 0, 0, 30));
|
||||
|
||||
int x = 10;
|
||||
QUI::label(labTotal_, this, x, 5, 100, 24, "共0条");
|
||||
QUI::button(btnFirst_, this, x += 110, 5, 60, 24, "首页");
|
||||
QUI::button(btnPrev_, this, x += 70, 5, 60, 24, "上一页");
|
||||
QUI::label(labPage_, this, x += 70, 5, 100, 25, "0/0");
|
||||
QUI::button(btnNext_, this, x += 110, 5, 60, 24, "下一页");
|
||||
QUI::button(btnLast_, this, x += 70, 5, 60, 24, "尾页");
|
||||
|
||||
labPage_.setAlignment(Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void PageCtrl::setPage(int pageId, int total)
|
||||
{
|
||||
curPage_ = pageId;
|
||||
int pageCount = total/pageSize_;
|
||||
if (total%pageSize_ > 0) { pageCount++; }
|
||||
|
||||
std::string s = "共" + std::to_string(total) + "条";
|
||||
labTotal_.setText(s.c_str());
|
||||
|
||||
s = std::to_string(curPage_) + "/" + std::to_string(pageCount);
|
||||
labPage_.setText(s.c_str());
|
||||
}
|
||||
207
src/widgets/uihelper.h
Normal file
207
src/widgets/uihelper.h
Normal file
@@ -0,0 +1,207 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QtCharts/QChart>
|
||||
#include <QChartView>
|
||||
#include <QBarSeries>
|
||||
#include <QBarSet>
|
||||
#include <QBarCategoryAxis>
|
||||
#include <QValueAxis>
|
||||
#include <QDateTimeAxis>
|
||||
#include <QDateTime>
|
||||
#include <QLineSeries>
|
||||
#include <QSplineSeries>
|
||||
|
||||
#include <QTableWidget>
|
||||
#include <QTableWidgetItem>
|
||||
#include <QHeaderView>
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
#include <QTextEdit>
|
||||
|
||||
using namespace QtCharts;
|
||||
|
||||
using MapLabelPair = std::map<std::string, std::pair<std::shared_ptr<QLabel>, std::shared_ptr<QLabel>>>;
|
||||
|
||||
class LabelPairH;
|
||||
class LabelPairV;
|
||||
|
||||
class UiStyle
|
||||
{
|
||||
public:
|
||||
static std::string BTN;
|
||||
};
|
||||
|
||||
class QUI
|
||||
{
|
||||
public:
|
||||
static std::shared_ptr<QLabel> label(QWidget* parent, int x, int y, int w, int h, std::string text, std::string sty="");
|
||||
|
||||
static void label(QLabel& lab, QWidget* parent, int x, int y, int w, int h, std::string text, std::string sty = "");
|
||||
|
||||
static void labelImage(QLabel& lab, QWidget* parent, int x, int y, int w, int h, std::string img);
|
||||
|
||||
static std::shared_ptr<LabelPairH> labelPair(QWidget* parent, int x, int y, int w, int h, int w1, std::string k, std::string v="");
|
||||
static std::shared_ptr<LabelPairV> labelPairV(QWidget* parent, int x, int y, int w, int h, int h1, std::string k, std::string v = "");
|
||||
|
||||
static void button(QPushButton& btn, QWidget* parent, int x, int y, int w, int h, std::string text, std::string sty = "");
|
||||
static QPushButton* button(QWidget* parent, int x, int y, int w, int h, std::string text, std::string sty = "");
|
||||
|
||||
//static std::shared_ptr<QComboBox> combox(QWidget* parent, int x, int y, int w, int h, std::vector<std::string>& items);
|
||||
|
||||
static void combox(QComboBox& comb, QWidget* parent, int x, int y, int w, int h, std::vector<std::string> items, std::string v="");
|
||||
|
||||
static void lineedit(QLineEdit& line, QWidget* parent, int x, int y, int w, int h);
|
||||
|
||||
static void setBackground(QWidget* w, std::string name, QColor color=QColor(29, 54, 102), std::string border="border-radius:5px;");
|
||||
};
|
||||
|
||||
class Panel : public QWidget
|
||||
{
|
||||
public:
|
||||
Panel(QWidget* parent, QRect rt, std::string title="");
|
||||
void setBackground(QColor color, std::string border="border-radius:1px;border:1px solid gray;");
|
||||
QLabel labBkg_;
|
||||
QLabel labIcon_;
|
||||
QLabel labTitle_;
|
||||
};
|
||||
|
||||
|
||||
class ChartBarView : public QChartView
|
||||
{
|
||||
public:
|
||||
ChartBarView(QWidget* parent, QRect rt, int xfrag=5);
|
||||
|
||||
void setTitle(std::string title);
|
||||
|
||||
std::shared_ptr<QChart> chart();
|
||||
|
||||
QBarSet& addItem(std::string name);
|
||||
void updateItem(int index, std::vector<double>& vd);
|
||||
QBarSet* getBar(int index);
|
||||
|
||||
void setBackground(QColor& color);
|
||||
|
||||
void setAxisXTick(std::vector<std::string>& vecTick);
|
||||
|
||||
public:
|
||||
std::shared_ptr<QChart> chart_;
|
||||
std::shared_ptr<QBarSeries> series_;
|
||||
|
||||
// X轴
|
||||
std::shared_ptr<QBarCategoryAxis> axisX_;
|
||||
// Y轴左侧
|
||||
std::shared_ptr<QValueAxis> axisYLeft_;
|
||||
|
||||
int xfrag_;
|
||||
|
||||
QLabel labTitle_;
|
||||
};
|
||||
|
||||
class ChartLineView : QChartView
|
||||
{
|
||||
public:
|
||||
ChartLineView(QWidget* parent, QRect rt);
|
||||
void setAxisX(double min, double max, int tickCount, std::string fmt = "hh:mm");
|
||||
void setAxisYLeft(double min, double max, double tickCount, std::string fmt = "%0.1f");
|
||||
void addItem(std::string name);
|
||||
void updateItem(int index, std::vector<std::pair<double, double>>& vd);
|
||||
private:
|
||||
std::shared_ptr<QChart> chart_;
|
||||
std::shared_ptr<QDateTimeAxis> axisX;
|
||||
std::shared_ptr<QValueAxis> axisY;
|
||||
std::vector<std::shared_ptr<QLineSeries>> vecSeries_;
|
||||
};
|
||||
|
||||
class ProgressView : public QWidget
|
||||
{
|
||||
public:
|
||||
ProgressView(QWidget* parent, int x, int y, int h, int w=3, int d=1, int n=50);
|
||||
void setVal(int v);
|
||||
|
||||
int num_;
|
||||
QLabel labVal_;
|
||||
QLabel labBarBkg_;
|
||||
std::vector<std::shared_ptr<QLabel>> vecBar_;
|
||||
};
|
||||
|
||||
class LabelPairV
|
||||
{
|
||||
public:
|
||||
LabelPairV(QWidget* parent, QRect rt, int w, std::string k, std::string v);
|
||||
void setVal(std::string v, std::string sty = "");
|
||||
void setValStyle(std::string sty);
|
||||
void setKeyStyle(std::string sty);
|
||||
void setStyle(std::string styK, std::string styV = "");
|
||||
QLabel labK_;
|
||||
QLabel labV_;
|
||||
};
|
||||
|
||||
class LabelPairH
|
||||
{
|
||||
public:
|
||||
LabelPairH(QWidget* parent, QRect rt, int w, std::string k, std::string v);
|
||||
void setVal(std::string v, std::string sty="");
|
||||
void setValStyle(std::string sty);
|
||||
void setKeyStyle(std::string sty);
|
||||
void setStyle(std::string styK, std::string styV="");
|
||||
QLabel labK_;
|
||||
QLabel labV_;
|
||||
};
|
||||
|
||||
|
||||
class TableBase : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TableBase(QWidget* parent, int rowMax, int colMax);
|
||||
|
||||
~TableBase();
|
||||
|
||||
void setGeometry(int x, int y, int w, int h);
|
||||
|
||||
void setHeaderH(std::vector<std::string> vecHeader);
|
||||
|
||||
void setHeaderWidth(std::vector<int> vecWidth);
|
||||
|
||||
void setOperate(std::vector<std::string> vecOperate, std::function<void(int, std::string)> cb);
|
||||
|
||||
void setRowData(int row, std::vector<std::string> vd);
|
||||
|
||||
void clear();
|
||||
|
||||
std::shared_ptr<QTableWidget> widget();
|
||||
|
||||
public:
|
||||
void onOperate(int row, std::string oper);
|
||||
|
||||
private:
|
||||
std::vector<std::string> vecOperate_;
|
||||
std::vector<std::shared_ptr<QWidget>> vecWidgetOper_;
|
||||
std::function<void(int, std::string)> cbOper_ = nullptr;
|
||||
std::shared_ptr<QTableWidget> widget_;
|
||||
};
|
||||
|
||||
class PageCtrl : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PageCtrl(QWidget* parent, QRect rt, int pageSize=10);
|
||||
void setPage(int pageId, int total);
|
||||
|
||||
int pageSize_ = 0;
|
||||
int curPage_ = 0;
|
||||
|
||||
QLabel labTotal_;
|
||||
QLabel labPage_;
|
||||
|
||||
QPushButton btnPrev_;
|
||||
QPushButton btnNext_;
|
||||
QPushButton btnFirst_;
|
||||
QPushButton btnLast_;
|
||||
};
|
||||
Reference in New Issue
Block a user