合并代码

This commit is contained in:
ym1026
2025-09-01 17:01:35 +08:00
68 changed files with 3110 additions and 618 deletions

View File

@@ -5,5 +5,6 @@
"user": "root", "user": "root",
"passwd": "123456", "passwd": "123456",
"dbname": "ees" "dbname": "ees"
} },
"token":""
} }

Binary file not shown.

View File

@@ -66,6 +66,7 @@ include_directories(
${THIRDPARTY_PATH} ${THIRDPARTY_PATH}
${THIRDPARTY_PATH}/mysql/include ${THIRDPARTY_PATH}/mysql/include
${THIRDPARTY_PATH}/nlohmann_json-3.11.2 ${THIRDPARTY_PATH}/nlohmann_json-3.11.2
${THIRDPARTY_PATH}/cpp-httplib-0.25.0
${PVLIBS_PATH}/include/pvserver ${PVLIBS_PATH}/include/pvserver
${PVLIBS_PATH}/include/rllib ${PVLIBS_PATH}/include/rllib
) )

View File

@@ -5,8 +5,8 @@
#include "app/Policy.h" #include "app/Policy.h"
#include "database/Dao.h" #include "database/Dao.h"
#include "common/JsonN.h" #include "common/JsonN.h"
#include "common/Snowflake.h"
#include "common/Utils.h"
void ElectPeriod::parse(std::string jsonstr) void ElectPeriod::parse(std::string jsonstr)
{ {
@@ -216,7 +216,6 @@ void AppData::initFromDB()
void AppData::init() void AppData::init()
{ {
this->initFromDB(); this->initFromDB();
this->initUser();
} }
std::shared_ptr<Station> AppData::getStation(int stationId) std::shared_ptr<Station> AppData::getStation(int stationId)
@@ -276,12 +275,35 @@ void AppData::loadStatData()
{ {
} }
static std::map<std::string, User> g_mapUser;
void AppData::initUser() std::string AppData::userLogin(std::string userId, std::string account)
{ {
auto dao = DaoEntity::create(""); for (auto iter = g_mapUser.begin(); iter!=g_mapUser.end(); ++iter)
std::vector<Fields> result; {
if (iter->second.userId == userId) // 重复登录
{
g_mapUser.erase(iter);
break;
} }
}
User user;
user.userId = userId;
user.account = account;
user.loginTime = Utils::time();
user.token = Snowflake::instance().getIdStr();
g_mapUser[user.token] = user;
return user.token;
}
User AppData::getUser(std::string token)
{
auto iter = g_mapUser.find(token);
if (iter != g_mapUser.end())
{
return iter->second;
}
return User();
}
int AppData::getWorkModeIdByName(std::string name) int AppData::getWorkModeIdByName(std::string name)
{ {

View File

@@ -6,6 +6,7 @@
#include <map> #include <map>
#include <unordered_map> #include <unordered_map>
#include "common/Fields.h" #include "common/Fields.h"
#include "app/Config.h"
class Station; class Station;
class Device; class Device;
@@ -13,6 +14,14 @@ class MyPolicy;
using VecPairSS = std::vector<std::pair<std::string, std::string>>; using VecPairSS = std::vector<std::pair<std::string, std::string>>;
struct User
{
std::string userId;
std::string account;
std::string token;
int64_t loginTime {};
};
struct DeviceType struct DeviceType
{ {
int typeId {}; int typeId {};
@@ -50,13 +59,11 @@ public:
void init(); void init();
void initFromDB(); void initFromDB();
// 读取统计数据: 今日统计数据,累计统计数据 // 读取统计数据: 今日统计数据,累计统计数据
void loadStatData(); void loadStatData();
void initUser(); std::string userLogin(std::string userId, std::string account);
User getUser(std::string token);
std::shared_ptr<Station> getStation(int stationId); std::shared_ptr<Station> getStation(int stationId);

View File

@@ -8,6 +8,8 @@
#include "app/Station.h" #include "app/Station.h"
#include "app/Device.h" #include "app/Device.h"
void Application::init() void Application::init()
{ {
// 初始化系统配置,读取配置文件 // 初始化系统配置,读取配置文件

View File

@@ -4,6 +4,7 @@
#include "common/JsonN.h" #include "common/JsonN.h"
#include "Logger.h" #include "Logger.h"
#include "AppData.h"
AppOption Config::option; AppOption Config::option;
@@ -34,5 +35,11 @@ bool Config::init(std::string filename)
XLOGI() << "[APP] load database config error: not found. host=" << option.database.host; XLOGI() << "[APP] load database config error: not found. host=" << option.database.host;
} }
if (jsonroot.contains("token"))
{
std::string token = jsonroot["token"];
option.useToken = !token.empty();
}
return true; return true;
} }

View File

@@ -14,6 +14,7 @@ struct DatabaseOption
struct AppOption struct AppOption
{ {
DatabaseOption database; DatabaseOption database;
bool useToken {true};
}; };
class Config class Config

11
src/app/Constants.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef _CONSTANTS_H_
#define _CONSTANTS_H_
#include <string>
namespace CONST
{
extern const std::string VAR;
}
#endif // !_CONSTANTS_H_

View File

@@ -15,8 +15,9 @@ std::shared_ptr<DaoEntity> DAO1::get(std::string tableName)
return std::make_shared<DaoEntity>(tableName); return std::make_shared<DaoEntity>(tableName);
} }
Errcode DAO1::login(std::shared_ptr<DaoEntity> dao, std::string account, std::string passwd, std::string& err) Errcode DAO1::login(std::shared_ptr<DaoEntity> dao, std::string account, std::string passwd, Fields& fields)
{ {
std::string err;
std::string t = Utils::timeStr(); std::string t = Utils::timeStr();
if (!dao) if (!dao)
{ {
@@ -29,23 +30,24 @@ Errcode DAO1::login(std::shared_ptr<DaoEntity> dao, std::string account, std::st
return Errcode::ERR_DB_CONN; return Errcode::ERR_DB_CONN;
} }
std::string sql = "SELECT * FROM user WHERE account='" + account + "';"; std::string sql = "SELECT u.*, ur.role_id FROM `user` u"
" LEFT JOIN user_role ur ON u.user_id = ur.user_id WHERE u.account=" + account + "';";
std::vector<Fields> res; std::vector<Fields> result;
bool ret = dao->exec(sql, res); bool ret = dao->exec(sql, result);
if (!ret) if (!ret)
{ {
err = "数据库操作错误"; err = "数据库操作错误";
DAO1::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err); DAO1::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
return Errcode::ERR_DB_CONN; return Errcode::ERR_DB_CONN;
} }
if (res.size() <=0) if (result.size() <=0)
{ {
err = "用户不存在"; err = "用户不存在";
DAO1::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err); DAO1::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
return Errcode::ERR_LOGIN_USER_NOTEXIST; return Errcode::ERR_LOGIN_USER_NOTEXIST;
} }
Fields& fields = res[0]; fields = result[0];
std::string userId = fields.value("user_id"); std::string userId = fields.value("user_id");
int loginCount = fields.get<int>("login_count"); int loginCount = fields.get<int>("login_count");
@@ -57,6 +59,15 @@ Errcode DAO1::login(std::shared_ptr<DaoEntity> dao, std::string account, std::st
return Errcode::ERR_LOGIN_PASSWD; return Errcode::ERR_LOGIN_PASSWD;
} }
// 读取用户权限
{
result.clear();
std::string sql = "SELECT rp.role_id, rp.permission_id, p.name FROM role_permission rp "
"LEFT JOIN permission p ON p.permission_id = rp.permission_id"
"WHERE rp.role_id = 1;";
}
err = "登录成功"; err = "登录成功";
// 数据库更新用户登录信息 // 数据库更新用户登录信息

View File

@@ -7,7 +7,7 @@ class DAO1
public: public:
static std::shared_ptr<DaoEntity> get(std::string tableName=""); static std::shared_ptr<DaoEntity> get(std::string tableName="");
static Errcode login(std::shared_ptr<DaoEntity> dao, std::string account, std::string passwd, std::string& err); static Errcode login(std::shared_ptr<DaoEntity> dao, std::string account, std::string passwd, Fields& res);
static bool writeSystemLog(std::shared_ptr<DaoEntity> dao, int type, std::string userId, std::string account, std::string text); static bool writeSystemLog(std::shared_ptr<DaoEntity> dao, int type, std::string userId, std::string account, std::string text);

View File

@@ -37,7 +37,7 @@ int Device::startComm()
{ {
if (!isOpen) if (!isOpen)
{ {
if (commEntity && commEntity->isAlive()) if (commEntity && commEntity->alive)
{ {
commEntity->close(); commEntity->close();
} }

24
src/app/errcode.cpp Normal file
View File

@@ -0,0 +1,24 @@
#include "errcode.h"
static std::unordered_map<Errcode, std::string> mapErr =
{
{Errcode::OK, "操作成功"},
{Errcode::ERR, "系统错误"},
{Errcode::ERR_TOKEN, "TOKEN错误"},
{Errcode::ERR_PARAM, "参数错误"},
{Errcode::ERR_PARAM_NUL, "缺少参数"},
{Errcode::ERR_LOGIN_USER_NOTEXIST, "用户不存在"},
{Errcode::ERR_LOGIN_PASSWD, "密码错误"},
{Errcode::ERR_DB_CONN, "数据库连接错误"},
{Errcode::ERR_DB_DUPLICATE, "数据库数据重复"},
{Errcode::ERR_DB_SQL, "数据库执行错误"},
{Errcode::ERR_DB_VAL, "参数值错误"},
};
std::string ErrcodeStr(Errcode code)
{
auto iter = mapErr.find(code);
return (iter != mapErr.end() ? iter->second : "");
}

View File

@@ -1,16 +1,28 @@
#pragma once #pragma once
#include <string>
#include <unordered_map>
enum class Errcode enum class Errcode
{ {
OK = 0, OK = 0,
ERR = 1,
ERR_TOKEN, // TOKEN错误
ERR_PARAM, // 参数错误
ERR_PARAM_NUL, // 缺少参数
ERR = 100, ERR_USER = 100,
ERR_DB_CONN = 101, // 数据库连接错误
ERR_DB_SQL = 102, // 数据库查询SQL错误
ERR_DB_DUPLICATE, // 数据重复
ERR_LOGIN_USER_NOTEXIST, // 登入错误,用户不存在 ERR_LOGIN_USER_NOTEXIST, // 登入错误,用户不存在
ERR_LOGIN_PASSWD, // 登入错误,密码不正确 ERR_LOGIN_PASSWD, // 登入错误,密码不正确
ERR_DEVICE = 200,
ERR_DB_CONN = 1001, // 数据库连接错误
ERR_DB_DUPLICATE = 1062, // Duplicate entry for key
ERR_DB_SQL = 1064, // 数据库查询SQL错误
ERR_DB_VAL = 1366, // 1366,Incorrect decimal value通常为参数值错误例如空值、值类型错误
}; };
extern std::string ErrcodeStr(Errcode code);

View File

@@ -96,9 +96,10 @@ string Fields::toStr()
string s; string s;
for (auto it = mapFields.begin(); it != mapFields.end(); it++) for (auto it = mapFields.begin(); it != mapFields.end(); it++)
{ {
s += ("{" + it->first + ":" + it->second + "} "); if (!s.empty()) s += ",";
s += ("\"" + it->first + "\":\"" + it->second + "\"");
} }
return s; return "{" + s + "}";
} }
string Fields::toSqlInsert(string tableName) string Fields::toSqlInsert(string tableName)

View File

@@ -1,4 +1,6 @@
#include <nlohmann/json.hpp> #pragma once
#include <nlohmann/json.hpp>
#include <fstream> #include <fstream>
#include <memory> #include <memory>
#include <iostream> #include <iostream>
@@ -68,7 +70,7 @@ public:
} }
catch (nlohmann::json::parse_error& e) catch (nlohmann::json::parse_error& e)
{ {
std::cout << "JSON parse error: " << e.what() << std::endl; std::cout << "JSON parse error: " << e.what() << "\n" << jsonstr << std::endl;
return false; return false;
} }
return true; return true;

View File

@@ -1,5 +1,9 @@
#include "Dao.h" #include "Dao.h"
#include "common/Utils.h" #include "common/Utils.h"
#include "common/Snowflake.h"
#include "common/JsonN.h"
#include "app/Application.h"
#include "app/AppData.h"
std::string DAO::sqlPageLimit(int index, int size) std::string DAO::sqlPageLimit(int index, int size)
{ {
@@ -8,19 +12,19 @@ std::string DAO::sqlPageLimit(int index, int size)
return " LIMIT " + std::to_string(startIndex) + "," + std::to_string(size); return " LIMIT " + std::to_string(startIndex) + "," + std::to_string(size);
} }
bool DAO::count(DaoEntity& dao, std::string tableName, std::string condition, int& count) Errcode DAO::count(DaoEntity& dao, std::string tableName, std::string condition, int& count)
{ {
std::string sql = "SELECT COUNT(*) count FROM " + tableName; std::string sql = "SELECT COUNT(*) count FROM " + tableName;
if (!condition.empty()) { sql += " WHERE " + condition; }; if (!condition.empty()) { sql += " WHERE " + condition; };
sql += ";"; sql += ";";
std::vector<Fields> result; std::vector<Fields> result;
bool ret = dao.exec(sql, result); int ret = dao.exec(sql, result);
if (ret) if (ret == 0)
{ {
count = (result.size() > 0) ? result[0].get<int>("count") : 0; count = (result.size() > 0) ? result[0].get<int>("count") : 0;
} }
return ret; return Errcode(ret);
} }
Errcode DAO::exec(std::shared_ptr<DaoEntity> dao, std::string sql) Errcode DAO::exec(std::shared_ptr<DaoEntity> dao, std::string sql)
@@ -31,7 +35,7 @@ Errcode DAO::exec(std::shared_ptr<DaoEntity> dao, std::string sql)
return Errcode::ERR_DB_CONN; return Errcode::ERR_DB_CONN;
} }
auto ret = dao->exec(sql); auto ret = dao->exec(sql);
return ret ? Errcode::OK : Errcode::ERR_DB_SQL; return Errcode(ret);
} }
Errcode DAO::exec(std::shared_ptr<DaoEntity> dao, std::string sql, vector<Fields>& result) Errcode DAO::exec(std::shared_ptr<DaoEntity> dao, std::string sql, vector<Fields>& result)
@@ -42,68 +46,109 @@ Errcode DAO::exec(std::shared_ptr<DaoEntity> dao, std::string sql, vector<Fields
return Errcode::ERR_DB_CONN; return Errcode::ERR_DB_CONN;
} }
auto ret = dao->exec(sql, result); auto ret = dao->exec(sql, result);
return ret ? Errcode::OK : Errcode::ERR_DB_SQL; return Errcode(ret);
} }
Errcode DAO::query(std::shared_ptr<DaoEntity> dao, std::string tableName, std::vector<std::string> keys, std::string condition)
static bool QueryCount(DaoEntity& dao, std::string sqlFrom, int& count) {
std::string sql;
return DAO::exec(dao, sql);
}
Errcode DAO::queryPagination(std::shared_ptr<DaoEntity> dao, std::string tableName, std::vector<std::string> keys, std::string condition)
{
std::string sql;
return DAO::exec(dao, sql);
}
Errcode DAO::insert(std::shared_ptr<DaoEntity> dao, std::string tableName, Fields params)
{
return DAO::exec(dao, params.toSqlInsert(tableName));
}
Errcode DAO::update(std::shared_ptr<DaoEntity> dao, std::string tableName, Fields params, std::string primaryKey)
{
std::string primaryVal = params.remove(primaryKey);
if (primaryVal.empty())
{
XLOGE() << "DAO update [" + tableName + "] failed, " << primaryKey << "=NULL.";
return Errcode::ERR_PARAM;
}
if (params.size() == 0)
{
XLOGE() << "DAO update [" + tableName + "] failed, params size=0.";
return Errcode::ERR_PARAM_NUL;
}
std::string condition = "WHERE " + primaryKey + "='" + primaryVal + "'";
string sql = params.toSqlUpdate(tableName, condition);
return DAO::exec(dao, sql);
}
Errcode DAO::remove(std::shared_ptr<DaoEntity> dao, std::string tableName, std::string primaryKey, std::string val)
{
std::string sql = "DELETE from `" + tableName + "` WHERE " + primaryKey + "='" + val + "';";
return DAO::exec(dao, sql);
}
static Errcode QueryCount(DaoEntity& dao, std::string sqlFrom, int& count)
{ {
std::vector<Fields> result; std::vector<Fields> result;
bool ret = dao.exec("SELECT COUNT(*) count " + sqlFrom, result); int ret = dao.exec("SELECT COUNT(*) count " + sqlFrom, result);
if (ret) if (ret != 0)
{ {
count = (result.size() > 0) ? result[0].get<int>("count") : 0; count = (result.size() > 0) ? result[0].get<int>("count") : 0;
} }
return ret; return Errcode(ret);
} }
static bool QueryPagination(std::string sqlFields, std::string sqlCondition, PageInfo& page, vector<Fields>& result) static Errcode QueryPagination(std::string sqlFields, std::string sqlCondition, PageInfo& page, vector<Fields>& result)
{ {
DaoEntity dao(""); DaoEntity dao("");
if (!dao.isConnected())
int count {0};
if (!QueryCount(dao, sqlCondition, count))
{ {
return false; return Errcode::ERR_DB_CONN;
}
int count {0};
Errcode err = QueryCount(dao, sqlCondition, count);
if (err != Errcode::OK)
{
return err;
} }
page.total = count; page.total = count;
std::string sql = "SELECT " + sqlFields + " " + sqlCondition + DAO::sqlPageLimit(page.index, page.size); std::string sql = "SELECT " + sqlFields + " " + sqlCondition + DAO::sqlPageLimit(page.index, page.size);
bool ret = dao.exec(sql, result); int ret = dao.exec(sql, result);
if (!ret) return Errcode(ret);
{
XLOGE() << "DAO database error: sql=" << sql;
}
return ret;
} }
// 新增用户信息 // 新增用户信息
Errcode DAO::insertUser(Fields& params) Errcode DAO::insertUser(Fields& params)
{ {
std::string createTime = Utils::timeStr();
auto dao = DaoEntity::create(DMUser::TABLENAME);
std::string account = params.value(DMUser::ACCOUNT); std::string account = params.value(DMUser::ACCOUNT);
if (account.empty())
std::string userRoleId = params.remove(DMRole::ROLE_ID);
// step1: 查询
std::vector<Fields> result;
bool ret = dao->exec("SELECT * from user WHERE account='" + account + "';", result);
if (!ret)
{ {
return Errcode::ERR_DB_CONN; return Errcode::ERR_PARAM;
}
// step1: 查询检查登录名是否已经存在
std::vector<Fields> result;
auto dao = DaoEntity::create(DMUser::TABLENAME);
int ret = dao->exec("SELECT * from user WHERE account='" + account + "';", result);
if (ret != 0)
{
return Errcode(ret);
} }
if (result.size() > 0) if (result.size() > 0)
{ {
return Errcode::ERR_DB_DUPLICATE; return Errcode::ERR_DB_DUPLICATE;
} }
std::string createTime = Utils::timeStr();
params.set(DMUser::USER_ID, Snowflake::instance().getIdStr());
params.set(DMUser::CREATETIME, createTime); params.set(DMUser::CREATETIME, createTime);
params.set(DMUser::PASSWD, "123456");
ret = dao->insertFields(params); ret = dao->insertFields(params);
if (!ret) if (ret != 0)
{ {
return Errcode::ERR_DB_SQL; return Errcode(ret);
} }
std::string userRoleId = params.remove(DMRole::ROLE_ID);
if (!userRoleId.empty()) if (!userRoleId.empty())
{ {
Fields paramsUserRole; Fields paramsUserRole;
@@ -115,20 +160,79 @@ Errcode DAO::insertUser(Fields& params)
return Errcode::OK; return Errcode::OK;
} }
Errcode DAO::login(std::shared_ptr<DaoEntity> dao, std::string account, std::string passwd, Fields& fields)
{
if (!dao) { dao = std::make_shared<DaoEntity>(""); }
if (!dao->isConnected())
{
//DAO1::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
return Errcode::ERR_DB_CONN;
}
std::string t = Utils::timeStr();
std::string sql = "SELECT u.*, ur.role_id FROM `user` u"
" LEFT JOIN user_role ur ON u.user_id = ur.user_id WHERE u.account='" + account + "';";
std::vector<Fields> result;
int ret = dao->exec(sql, result);
if (ret != 0)
{
//DAO1::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
return Errcode(ret);
}
if (result.size() <=0)
{
//DAO1::writeSystemLog(dao, 2, "", account, "用户登录失败:" + err);
return Errcode::ERR_LOGIN_USER_NOTEXIST;
}
fields = result[0];
std::string userId = fields.value("user_id");
int loginCount = fields.get<int>("login_count");
// 判断密码
if (passwd != fields.remove("passwd"))
{
//DAO1::writeSystemLog(dao, 2, userId, account, "用户登录失败:" + err);
return Errcode::ERR_LOGIN_PASSWD;
}
// 数据库更新用户登录信息
//sql = "UPDATE user SET login_time='" + t + "', login_count='" + std::to_string(loginCount + 1) + "' WHERE user_id = '" + userId + "'; ";
//ret = dao->exec(sql);
//if (ret != 0)
//{
// XLOGE() << "更新用户登录信息失败sql=" << sql;
//}
//DAO1::writeSystemLog(dao, 2, userId, account, "用户登录成功");
return Errcode::OK;
}
Errcode DAO::queryRolePermission(std::shared_ptr<DaoEntity> dao, int roleId, vector<Fields>& result)
{
std::string sql = "SELECT rp.role_id, rp.permission_id, p.name FROM role_permission rp"
" LEFT JOIN permission p ON p.permission_id = rp.permission_id"
" WHERE rp.is_open='1' AND rp.role_id ='" + std::to_string(roleId) + "';";
return DAO::exec(dao, sql, result);
}
Errcode DAO::queryRolePermission(std::shared_ptr<DaoEntity> dao, vector<Fields>& result)
{
// 查询 role 的 permission
std::string sql = "SELECT rp.role_id, rp.permission_id, rp.is_open, r.name role_name, p.name permission_name FROM role_permission rp"
" LEFT JOIN `role` r ON r.role_id = rp.role_id"
" LEFT JOIN permission p ON p.permission_id = rp.permission_id"
" WHERE rp.is_open='1';";
return DAO::exec(dao, sql, result);
}
// 分页查询用户信息列表 // 分页查询用户信息列表
bool DAO::queryUserList(PageInfo& pageInfo, vector<Fields>& result) Errcode DAO::queryUserList(PageInfo& pageInfo, vector<Fields>& result)
{ {
std::string sqlFields = "u.*, r.role_id , r.name role_name"; std::string sqlFields = "u.user_id, u.account, u.name, u.phone, u.age, u.email, u.gender, u.is_open, u.create_time, u.update_time, r.role_id , r.name role_name";
std::string sqlCondition = "FROM USER u LEFT JOIN user_role ur ON ur.user_id = u.user_id LEFT JOIN ROLE r ON r.role_id =ur.role_id"; std::string sqlCondition = "FROM USER u LEFT JOIN user_role ur ON ur.user_id = u.user_id LEFT JOIN ROLE r ON r.role_id =ur.role_id";
DaoEntity dao(""); return QueryPagination(sqlFields, sqlCondition, pageInfo, result);
bool ret = QueryPagination(sqlFields, sqlCondition, pageInfo, result);
if (!ret)
{
XLOGE() << "DAO database error: queryUserList failed.";
}
return ret;
} }
Errcode DAO::updateUserById(Fields& params) Errcode DAO::updateUserById(Fields& params)
@@ -141,10 +245,10 @@ Errcode DAO::updateUserById(Fields& params)
if (params.size() > 0) if (params.size() > 0)
{ {
bool ret = dao->updateFields(params, "WHERE " + DMUser::USER_ID + "='" + userId + "'"); int ret = dao->updateFields(params, "WHERE " + DMUser::USER_ID + "='" + userId + "'");
if (!ret) if (ret != 0)
{ {
return Errcode::ERR_DB_SQL; return Errcode(ret);
} }
} }
if (!roleId.empty()) if (!roleId.empty())
@@ -154,43 +258,137 @@ Errcode DAO::updateUserById(Fields& params)
paramsUserRole.set(DMUserRole::USER_ID, userId); paramsUserRole.set(DMUserRole::USER_ID, userId);
paramsUserRole.set(DMUserRole::ROLE_ID, roleId); paramsUserRole.set(DMUserRole::ROLE_ID, roleId);
paramsUserRole.set(DMUserRole::UPDATETIME, createTime); paramsUserRole.set(DMUserRole::UPDATETIME, createTime);
bool ret = dao->duplicateUpdate(paramsUserRole, {DMUserRole::ROLE_ID}); int ret = dao->duplicateUpdate(paramsUserRole, {DMUserRole::ROLE_ID});
if (!ret) if (ret != 0)
{ {
return Errcode::ERR_DB_SQL; return Errcode(ret);
} }
} }
return Errcode::OK; return Errcode::OK;
} }
Errcode DAO::deleteUserById(std::string userId)
{
std::string sql = "DELETE from user WHERE user_id='" + userId + "';";
return DAO::exec(NULL, sql);
}
Errcode DAO::queryPermissionList(PageInfo& pageInfo, vector<Fields>& result)
{
std::string sqlFrom = "FROM " + DMPermission::TABLENAME;
return QueryPagination("*", sqlFrom, pageInfo, result);
}
Errcode DAO::insertPermission(Fields& params)
{
return DAO::exec(NULL, params.toSqlInsert(DMPermission::TABLENAME));
}
Errcode DAO::updatePermissionById(Fields& params)
{
std::string primaryKey = DMPermission::PERMISSION_ID;
std::string primaryVal = params.remove(primaryKey);
if (primaryVal.empty())
{
return Errcode::ERR_DB_SQL;
}
std::string condition = "WHERE " + primaryKey + "='" + primaryVal + "'";
string sql = params.toSqlUpdate(DMPermission::TABLENAME, condition);
return DAO::exec(NULL, sql);
}
Errcode DAO::deletePermissionById(std::string permissionId)
{
std::string sql = "DELETE from permission WHERE permission_id='" + permissionId + "';";
return DAO::exec(NULL, sql);
}
Errcode DAO::queryRoleList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result) Errcode DAO::queryRoleList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result)
{ {
std::string sql = "SELECT * FROM " + DMRole::TABLENAME + ";"; std::string sql = "SELECT * FROM " + DMRole::TABLENAME + ";";
return DAO::exec(dao, sql, result); return DAO::exec(dao, sql, result);
} }
bool DAO::queryRoleList(PageInfo& pageInfo, vector<Fields>& result) Errcode DAO::queryRoleList(PageInfo& pageInfo, vector<Fields>& result)
{ {
DaoEntity dao(""); std::string sqlFields = "";
std::string sqlFrom = "FROM " + DMRole::TABLENAME; std::string sqlCondition = "FROM " + DMRole::TABLENAME;
bool ret = QueryPagination("*", sqlFrom, pageInfo, result); return QueryPagination("*", sqlCondition, pageInfo, result);
if (!ret)
{
XLOGE() << "DAO database error: queryRoleList failed.";
}
return ret;
} }
bool DAO::queryPermissionList(PageInfo& pageInfo, vector<Fields>& result) Errcode DAO::updateRolePermission(std::shared_ptr<DaoEntity> dao, std::string roleId, std::string permission)
{ {
DaoEntity dao(""); NJsonNode jnode;
std::string sqlFrom = "FROM " + DMPermission::TABLENAME; NJson::parse(permission, jnode);
bool ret = QueryPagination("*", sqlFrom, pageInfo, result); std::vector<Fields> vec;
if (!ret) for (auto& item: jnode)
{ {
XLOGE() << "DAO database error: queryPermissionList failed."; std::string permissionId;
if (item.is_number()) { permissionId = std::to_string(item.get<int>()); }
if (item.is_string()) { permissionId = item.get<std::string>(); }
if (!permissionId.empty())
{
Fields field;
field.set("role_id", roleId);
field.set("permission_id", permissionId);
vec.emplace_back(field);
} }
return ret; }
dao->setTableName(DMRolePermission::TABLENAME);
std::string sqlDel = "DELETE from " + DMRolePermission::TABLENAME + " WHERE role_id='" + roleId + "';";
int ret = dao->exec(sqlDel);
if (ret != 0 ){ return Errcode(ret); };
ret = dao->insertFields(vec);
if (ret != 0) { return Errcode(ret); };
return Errcode::OK;
}
// 新增角色
Errcode DAO::insertRole(Fields& params)
{
std::string permission = params.remove("permission");
std::string name = params.value("name");
auto dao = DaoEntity::create(DMRole::TABLENAME);
auto err = DAO::insert(dao, DMRole::TABLENAME, params);
if (err == Errcode::OK && !permission.empty())
{
// 查询获取 roleId
std::vector<Fields> res;
std::string sql = "SELECT * FROM " + DMRole::TABLENAME + " WHERE name='" + name + "';";
err = DAO::exec(dao, sql, res);
if (err == Errcode::OK && res.size() > 0)
{
std::string roleId = res[0].value("role_id");
err = DAO::updateRolePermission(dao, roleId, permission);
}
}
return err;
}
// 更新角色
Errcode DAO::updateRoleById(Fields& params)
{
auto roleId = params.value(DMRole::ROLE_ID);
if (roleId.empty())
{
return Errcode::ERR_DB_SQL;
}
auto permission = params.remove("permission");
auto dao = DaoEntity::create(DMRole::TABLENAME);
auto err = DAO::update(dao, DMRole::TABLENAME, params, DMRole::ROLE_ID);
if (err == Errcode::OK && !permission.empty())
{
err = DAO::updateRolePermission(dao, roleId, permission);
}
return err;
}
// 删除角色
Errcode DAO::deleteRoleById(std::string userId)
{
return DAO::remove(NULL, DMRole::TABLENAME, DMRole::ROLE_ID, userId);
} }
Errcode DAO::insertStation(Fields& params) Errcode DAO::insertStation(Fields& params)
@@ -201,7 +399,7 @@ Errcode DAO::insertStation(Fields& params)
params.check(DMStation::LONGITUDE, "", "NULL"); params.check(DMStation::LONGITUDE, "", "NULL");
std::string sql = params.toSqlInsert(DMStation::TABLENAME); std::string sql = params.toSqlInsert(DMStation::TABLENAME);
return DAO::exec(dao, sql); return DAO::insert(NULL, DMStation::TABLENAME, params);
} }
// 查询场站信息列表 // 查询场站信息列表
@@ -212,33 +410,16 @@ Errcode DAO::queryStationList(std::shared_ptr<DaoEntity> dao, vector<Fields>& re
} }
// 分页查询场站信息列表 // 分页查询场站信息列表
bool DAO::queryStationList(PageInfo& pageInfo, vector<Fields>& result) Errcode DAO::queryStationList(PageInfo& pageInfo, vector<Fields>& result)
{ {
DaoEntity dao("");
std::string sqlFrom = "FROM " + DMStation::TABLENAME; std::string sqlFrom = "FROM " + DMStation::TABLENAME;
bool ret = QueryPagination("*", sqlFrom, pageInfo, result); return QueryPagination("*", sqlFrom, pageInfo, result);
if (!ret)
{
XLOGE() << "DAO database error: queryStationList failed.";
}
return ret;
} }
Errcode DAO::updateStationById(Fields& params) Errcode DAO::updateStationById(Fields& params)
{ {
std::string stationId = params.value(DMStation::STATION_ID); std::string primaryKey = DMStation::STATION_ID;
if (stationId.empty()) return DAO::update(NULL, DMStation::TABLENAME, params, primaryKey);
{
return Errcode::ERR_DB_SQL;
}
params.remove(DMStation::STATION_ID);
auto dao = DaoEntity::create(DMStation::TABLENAME);
bool ret = dao->updateFields(params, "WHERE " + DMStation::STATION_ID + "='" + stationId + "'");
if (!ret)
{
return Errcode::ERR_DB_SQL;
}
return Errcode::OK;
} }
// 查询设备信息列表 // 查询设备信息列表
@@ -249,16 +430,10 @@ Errcode DAO::queryDeviceList(std::shared_ptr<DaoEntity> dao, vector<Fields>& res
} }
// 分页查询设备信息列表 // 分页查询设备信息列表
bool DAO::queryDeviceList(PageInfo& pageInfo, vector<Fields>& result) Errcode DAO::queryDeviceList(PageInfo& pageInfo, vector<Fields>& result)
{ {
DaoEntity dao("");
std::string sqlFrom = "FROM " + DMDevice::TABLENAME; std::string sqlFrom = "FROM " + DMDevice::TABLENAME;
bool ret = QueryPagination("*", sqlFrom, pageInfo, result); return QueryPagination("*", sqlFrom, pageInfo, result);
if (!ret)
{
XLOGE() << "DAO database error: queryDeviceList failed.";
}
return ret;
} }
// 查询设备类型定义 // 查询设备类型定义
@@ -275,26 +450,14 @@ Errcode DAO::insertDevice(Fields& params)
Errcode DAO::updateDeviceById(Fields& params) Errcode DAO::updateDeviceById(Fields& params)
{ {
std::string deviceId = params.value(DMDevice::DEVICE_ID); return DAO::update(NULL, DMDevice::TABLENAME, params, DMDevice::DEVICE_ID);
if (deviceId.empty())
{
return Errcode::ERR_DB_SQL;
}
std::string sql = params.toSqlUpdate(DMDevice::TABLENAME, "WHERE " + DMDevice::DEVICE_ID + "='" + deviceId + "'");
return DAO::exec(NULL, sql);
} }
// 策略管理 // 策略管理
bool DAO::queryPolicyList(PageInfo& pageInfo, vector<Fields>& result) Errcode DAO::queryPolicyList(PageInfo& pageInfo, vector<Fields>& result)
{ {
auto dao = DaoEntity::create("");
std::string sqlFrom = "FROM " + DMPolicy::TABLENAME; std::string sqlFrom = "FROM " + DMPolicy::TABLENAME;
bool ret = QueryPagination("*", sqlFrom, pageInfo, result); return QueryPagination("*", sqlFrom, pageInfo, result);
if (!ret)
{
XLOGE() << "DAO database error: queryPolicyList failed.";
}
return ret;
} }
Errcode DAO::queryPolicyList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result) Errcode DAO::queryPolicyList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result)
@@ -304,32 +467,78 @@ Errcode DAO::queryPolicyList(std::shared_ptr<DaoEntity> dao, vector<Fields>& res
} }
Errcode DAO::insertPolicy(Fields& params) Errcode DAO::insertPolicy(Fields& params)
{ {
return DAO::exec(NULL, params.toSqlInsert(DMPolicy::TABLENAME)); return DAO::insert(NULL, DMPolicy::TABLENAME, params);
} }
Errcode DAO::updatePolicyById(Fields& params) Errcode DAO::updatePolicyById(Fields& params)
{ {
std::string policyId = params.value(DMPolicy::POLICY_ID); return DAO::update(NULL, DMPolicy::TABLENAME, params, DMPolicy::POLICY_ID);
if (policyId.empty())
{
return Errcode::ERR_DB_SQL;
} }
std::string sql = params.toSqlUpdate(DMPolicy::TABLENAME, "WHERE " + DMPolicy::POLICY_ID + "='" + policyId + "'"); Errcode DAO::deletePolicyById(std::string policyId)
return DAO::exec(NULL, sql); {
return DAO::remove(NULL, DMPolicy::TABLENAME, DMPolicy::POLICY_ID, policyId);
} }
// 系统日志管理 // 系统日志管理
bool DAO::querySystemLogList(PageInfo& pageInfo, vector<Fields>& result) Errcode DAO::querySystemLogList(PageInfo& pageInfo, vector<Fields>& result)
{ {
DaoEntity dao(""); std::string sqlFrom = "FROM " + DMLogSystem::TABLENAME;
std::string sqlFrom = "FROM " + DMSystemLog::TABLENAME; return QueryPagination("*", sqlFrom, pageInfo, result);
bool ret = QueryPagination("*", sqlFrom, pageInfo, result); }
if (!ret) Errcode DAO::insertSystemLog(Fields& params)
{ {
XLOGE() << "DAO database error: querySystemLogList failed."; params.set(DMLogAlert::LOG_ID, Snowflake::instance().getIdStr());
return DAO::insert(NULL, DMLogSystem::TABLENAME, params);
} }
return ret; Errcode DAO::updateSystemLogById(Fields& params)
{
return DAO::update(NULL, DMLogSystem::TABLENAME, params, DMLogSystem::LOG_ID);
} }
Errcode DAO::insertSystemLogSys(std::string content, int status)
{
Fields fields;
fields.set("type", 1);
fields.set("content", content);
fields.set("status", status);
return DAO::insertSystemLog(fields);
}
Errcode DAO::insertSystemLogUser(std::string token, std::string content, int status)
{
User user = Application::data().getUser(token);
Fields fields;
fields.set("type", 2);
fields.set("content", content);
fields.set("status", status);
fields.set("user_id", user.userId);
fields.set("user_account", user.account);
return DAO::insertSystemLog(fields);
}
Errcode DAO::insertSystemLogDevice(std::string deviceId, std::string content, int status)
{
Fields fields;
fields.set("type", 3);
fields.set("content", content);
fields.set("status", status);
fields.set("device_id", deviceId);
return DAO::insertSystemLog(fields);
}
Errcode DAO::queryAlertLogList(PageInfo& pageInfo, vector<Fields>& result)
{
std::string sqlFrom = "FROM " + DMLogAlert::TABLENAME;
return QueryPagination("*", sqlFrom, pageInfo, result);
}
Errcode DAO::insertAlertLog(Fields& params)
{
params.set(DMLogAlert::LOG_ID, Snowflake::instance().getIdStr());
return DAO::insert(NULL, DMLogAlert::TABLENAME, params);
}
Errcode DAO::updateAlertLogById(Fields& params)
{
return DAO::update(NULL, DMLogAlert::TABLENAME, params, DMLogAlert::LOG_ID);
}
Errcode DAO::queryStatDataList(std::shared_ptr<DaoEntity> dao, std::string startDate, std::string endDate, vector<Fields>& result) Errcode DAO::queryStatDataList(std::shared_ptr<DaoEntity> dao, std::string startDate, std::string endDate, vector<Fields>& result)
{ {
std::string sql = "SELECT * FROM " + DMStatStation::TABLENAME + " WHERE dt BETWEEN '" + startDate + "' AND '" + endDate + "';"; std::string sql = "SELECT * FROM " + DMStatStation::TABLENAME + " WHERE dt BETWEEN '" + startDate + "' AND '" + endDate + "';";
@@ -342,7 +551,6 @@ Errcode DAO::queryWorkModeDef(std::shared_ptr<DaoEntity> dao, vector<Fields>& re
return DAO::exec(dao, sql, result); return DAO::exec(dao, sql, result);
} }
Errcode DAO::queryPolicyTypeDef(std::shared_ptr<DaoEntity> dao, vector<Fields>& result) Errcode DAO::queryPolicyTypeDef(std::shared_ptr<DaoEntity> dao, vector<Fields>& result)
{ {
std::string sql = "SELECT * FROM " + DMDefPolicyType::TABLENAME + ";"; std::string sql = "SELECT * FROM " + DMDefPolicyType::TABLENAME + ";";

View File

@@ -9,38 +9,60 @@ class DAO
public: public:
static std::string sqlPageLimit(int index, int size); static std::string sqlPageLimit(int index, int size);
static bool count(DaoEntity& dao, std::string tableName, std::string condition, int& count); static Errcode count(DaoEntity& dao, std::string tableName, std::string condition, int& count);
static Errcode exec(std::shared_ptr<DaoEntity> dao, std::string sql); static Errcode exec(std::shared_ptr<DaoEntity> dao, std::string sql);
static Errcode exec(std::shared_ptr<DaoEntity> dao, std::string sql, vector<Fields>& result); static Errcode exec(std::shared_ptr<DaoEntity> dao, std::string sql, vector<Fields>& result);
static Errcode query(std::shared_ptr<DaoEntity> dao, std::string tableName, std::vector<std::string> keys, std::string condition);
static Errcode queryPagination(std::shared_ptr<DaoEntity> dao, std::string tableName, std::vector<std::string> keys, std::string condition);
static Errcode insert(std::shared_ptr<DaoEntity> dao, std::string tableName, Fields params);
static Errcode update(std::shared_ptr<DaoEntity> dao, std::string tableName, Fields params, std::string primaryKey);
static Errcode remove(std::shared_ptr<DaoEntity> dao, std::string tableName, std::string primaryKey, std::string val);
static Errcode login(std::shared_ptr<DaoEntity> dao, std::string account, std::string passwd, Fields& fields);
// 查询用户信息列表(分页) static Errcode queryRolePermission(std::shared_ptr<DaoEntity> dao, int roleId, vector<Fields>& result);
static bool queryUserList(PageInfo& pageInfo, vector<Fields>& result); static Errcode queryRolePermission(std::shared_ptr<DaoEntity> dao, vector<Fields>& result);
// 新增用户信息 // 查询用户列表(分页)
static Errcode queryUserList(PageInfo& pageInfo, vector<Fields>& result);
// 新增用户
static Errcode insertUser(Fields& params); static Errcode insertUser(Fields& params);
// 更新用户信息 // 更新用户
static Errcode updateUserById(Fields& params); static Errcode updateUserById(Fields& params);
// 删除用户
static Errcode deleteUserById(std::string userId);
// 查询角色信息列表(分页)
static bool queryRoleList(PageInfo& pageInfo, vector<Fields>& result);
// 查询角色信息列表
static Errcode queryRoleList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result);
// 查询权限信息列表(分页) // 查询权限信息列表(分页)
static bool queryPermissionList(PageInfo& pageInfo, vector<Fields>& result); static Errcode queryPermissionList(PageInfo& pageInfo, vector<Fields>& result);
// 新增权限
static Errcode insertPermission(Fields& params);
// 更新权限
static Errcode updatePermissionById(Fields& params);
// 删除权限
static Errcode deletePermissionById(std::string userId);
static Errcode updateRolePermission(std::shared_ptr<DaoEntity> dao, std::string roleId, std::string permission);
// 查询角色列表(分页)
static Errcode queryRoleList(PageInfo& pageInfo, vector<Fields>& result);
// 查询角色列表
static Errcode queryRoleList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result);
// 新增角色
static Errcode insertRole(Fields& params);
// 更新角色
static Errcode updateRoleById(Fields& params);
// 删除角色
static Errcode deleteRoleById(std::string userId);
// 查询场站信息列表(分页) // 查询场站信息列表(分页)
static bool queryStationList(PageInfo& pageInfo, vector<Fields>& result); static Errcode queryStationList(PageInfo& pageInfo, vector<Fields>& result);
// 查询场站信息列表 // 查询场站信息列表
static Errcode queryStationList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result); static Errcode queryStationList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result);
@@ -52,7 +74,7 @@ public:
// 查询设备信息列表(分页) // 查询设备信息列表(分页)
static bool queryDeviceList(PageInfo& pageInfo, vector<Fields>& result); static Errcode queryDeviceList(PageInfo& pageInfo, vector<Fields>& result);
// 查询设备信息列表 // 查询设备信息列表
static Errcode queryDeviceList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result); static Errcode queryDeviceList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result);
// 查询设备类型定义 // 查询设备类型定义
@@ -65,17 +87,28 @@ public:
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
// === 策略管理 === // === 策略管理 ===
// 分页查询策略信息列表 // 分页查询策略信息列表
static bool queryPolicyList(PageInfo& pageInfo, vector<Fields>& result); static Errcode queryPolicyList(PageInfo& pageInfo, vector<Fields>& result);
static Errcode queryPolicyList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result); static Errcode queryPolicyList(std::shared_ptr<DaoEntity> dao, vector<Fields>& result);
static Errcode insertPolicy(Fields& params); static Errcode insertPolicy(Fields& params);
static Errcode updatePolicyById(Fields& params); static Errcode updatePolicyById(Fields& params);
static Errcode deletePolicyById(std::string policyId);
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
// === 系统日志管理 === // === 系统日志管理 ===
// 分页查询系统日志列表 // 分页查询系统日志列表
static bool querySystemLogList(PageInfo& pageInfo, vector<Fields>& result); static Errcode querySystemLogList(PageInfo& pageInfo, vector<Fields>& result);
static Errcode insertSystemLog(Fields& params);
static Errcode updateSystemLogById(Fields& params);
static Errcode insertSystemLogSys(std::string content, int status);
static Errcode insertSystemLogUser(std::string token, std::string content, int status);
static Errcode insertSystemLogDevice(std::string deviceId, std::string content, int status);
static Errcode queryAlertLogList(PageInfo& pageInfo, vector<Fields>& result);
static Errcode insertAlertLog(Fields& params);
static Errcode updateAlertLogById(Fields& params);
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
// === 统计数据管理 === // === 统计数据管理 ===

View File

@@ -66,23 +66,23 @@ bool DaoEntity::isConnected()
return db_->isConnected(); return db_->isConnected();
} }
bool DaoEntity::exec(string sql) int DaoEntity::exec(string sql)
{ {
return db_->exec(sql); return db_->exec(sql);
} }
bool DaoEntity::exec(string sql, vector<Fields>& result) int DaoEntity::exec(string sql, vector<Fields>& result)
{ {
return db_->exec(sql, result); return db_->exec(sql, result);
} }
bool DaoEntity::insertFields(Fields& fields) int DaoEntity::insertFields(Fields& fields)
{ {
string sql = fields.toSqlInsert(tableName_); string sql = fields.toSqlInsert(tableName_);
return this->db_->exec(sql); return this->db_->exec(sql);
} }
bool DaoEntity::insertFields(vector<Fields>& vec_fields) int DaoEntity::insertFields(vector<Fields>& vec_fields)
{ {
//"insert into TABLE () values ()"; //"insert into TABLE () values ()";
string sql = "insert into " + tableName_; string sql = "insert into " + tableName_;
@@ -127,7 +127,7 @@ bool DaoEntity::insertFields(vector<Fields>& vec_fields)
return this->db_->exec(sql); return this->db_->exec(sql);
} }
bool DaoEntity::duplicateUpdate(Fields& fields, const vector<string>& keys) int DaoEntity::duplicateUpdate(Fields& fields, const vector<string>& keys)
{ {
//insert into device_attr(device_id, attr_id, attr_val) values('26', 'model', '型号1') on duplicate key update attr_val='型号1'; //insert into device_attr(device_id, attr_id, attr_val) values('26', 'model', '型号1') on duplicate key update attr_val='型号1';
string key; string key;
@@ -161,33 +161,34 @@ bool DaoEntity::duplicateUpdate(Fields& fields, const vector<string>& keys)
// }); // });
//} //}
bool DaoEntity::queryFields(string keys, const string& condition, vector<Fields>& result) int DaoEntity::queryFields(string keys, const string& condition, vector<Fields>& result)
{ {
ostringstream oss; ostringstream oss;
oss << "SELECT " + keys + " FROM " << tableName_ << (" " + condition) << "; "; oss << "SELECT " + keys + " FROM " << tableName_ << (" " + condition) << "; ";
return this->db_->exec(oss.str(), result); return this->db_->exec(oss.str(), result);
} }
bool DaoEntity::queryFields(string keys, const string& condition, PageInfo& page, vector<Fields>& result) int DaoEntity::queryFields(string keys, const string& condition, PageInfo& page, vector<Fields>& result)
{ {
int err = 0;
ostringstream oss; ostringstream oss;
oss << "SELECT count(1) total FROM `" << tableName_ << "` " << condition << ";"; oss << "SELECT count(1) total FROM `" << tableName_ << "` " << condition << ";";
vector<Fields> res_total; vector<Fields> res_total;
if (!this->db_->exec(oss.str().c_str(), res_total)) if (err = this->db_->exec(oss.str().c_str(), res_total))
{ {
return false; return err;
} }
if (res_total.size() <= 0) if (res_total.size() <= 0)
{ {
page.total = 0; page.total = 0;
return true; return err;
} }
page.total = res_total[0].get<int>("total"); page.total = res_total[0].get<int>("total");
if (page.total <= 0) if (page.total <= 0)
{ {
return true; return err;
} }
oss.str(""); oss.str("");
@@ -200,13 +201,13 @@ bool DaoEntity::queryFields(string keys, const string& condition, PageInfo& page
return this->db_->exec(oss.str().c_str(), result); return this->db_->exec(oss.str().c_str(), result);
} }
bool DaoEntity::updateFields(Fields& fields, const string& condition) int DaoEntity::updateFields(Fields& fields, const string& condition)
{ {
string sql = fields.toSqlUpdate(tableName_, condition); string sql = fields.toSqlUpdate(tableName_, condition);
return this->db_->exec(sql); return this->db_->exec(sql);
} }
bool DaoEntity::updateFields(Fields& fields, vector<string> vecKeys, const string& condition) int DaoEntity::updateFields(Fields& fields, vector<string> vecKeys, const string& condition)
{ {
string sql = fields.toSqlUpdate(tableName_, vecKeys, condition); string sql = fields.toSqlUpdate(tableName_, vecKeys, condition);
return this->db_->exec(sql); return this->db_->exec(sql);

View File

@@ -42,39 +42,39 @@ public:
/** /**
* 执行sql语句 * 执行sql语句
*/ */
bool exec(string sql); int exec(string sql);
/** /**
* 执行sql语句并返回执行查询的结果集 * 执行sql语句并返回执行查询的结果集
*/ */
bool exec(string sql, vector<Fields>& result); int exec(string sql, vector<Fields>& result);
/** /**
* 数据库插入一条数据, 需要先指定数据表名称 * 数据库插入一条数据, 需要先指定数据表名称
* @param: fields 写入的数据字段和值 * @param: fields 写入的数据字段和值
*/ */
bool insertFields(Fields& vecFields); int insertFields(Fields& vecFields);
/** /**
* 数据库插入多条数据, 需要先指定数据表名称 * 数据库插入多条数据, 需要先指定数据表名称
* @param: vecFields 写入的数据字段和值的集合 * @param: vecFields 写入的数据字段和值的集合
*/ */
bool insertFields(vector<Fields>& vecFields); int insertFields(vector<Fields>& vecFields);
/** /**
* 数据库插入多条数据UNIQUE索引或PRIMARY KEY重复时执行更新数据, 需要先指定数据表名称 * 数据库插入多条数据UNIQUE索引或PRIMARY KEY重复时执行更新数据, 需要先指定数据表名称
* @param: vecFields 写入的数据字段和值的集合 * @param: vecFields 写入的数据字段和值的集合
* @param: keys 数据重复时需要更新的字段 * @param: keys 数据重复时需要更新的字段
*/ */
bool duplicateUpdate(Fields& vecFields, const vector<string>& keys); int duplicateUpdate(Fields& vecFields, const vector<string>& keys);
/** /**
* 数据库查询,需要先指定数据表名称 * 数据库查询,需要先指定数据表名称
* @param: sql_c 查询条件,例:"where id='1'" * @param: sql_c 查询条件,例:"where id='1'"
* @param: result 查询的数据结果集 * @param: result 查询的数据结果集
*/ */
bool queryFields(string keys, const string& sql_c, vector<Fields>& result); int queryFields(string keys, const string& sql_c, vector<Fields>& result);
/** /**
* 数据库查询,需要先指定数据表名称 * 数据库查询,需要先指定数据表名称
@@ -82,14 +82,14 @@ public:
* @param: pageinfo 分页信息 * @param: pageinfo 分页信息
* @param: result 查询的数据结果集 * @param: result 查询的数据结果集
*/ */
bool queryFields(string keys, const string& sql_c, PageInfo& pageinfo, vector<Fields>& result); int queryFields(string keys, const string& sql_c, PageInfo& pageinfo, vector<Fields>& result);
/** /**
* 数据库更新,需要先指定数据表名称 * 数据库更新,需要先指定数据表名称
* @param: fields 要更新的数据字段和值 * @param: fields 要更新的数据字段和值
* @param: sql_c 更新条件 * @param: sql_c 更新条件
*/ */
bool updateFields(Fields& fields, const string& sql_c); int updateFields(Fields& fields, const string& sql_c);
/** /**
* 数据库更新,需要先指定数据表名称 * 数据库更新,需要先指定数据表名称
@@ -97,7 +97,7 @@ public:
* @param: vecKeys 要更新的字段名称 * @param: vecKeys 要更新的字段名称
* @param: cond 更新条件 * @param: cond 更新条件
*/ */
bool updateFields(Fields& fields, vector<string> vecKeys, const string& cond); int updateFields(Fields& fields, vector<string> vecKeys, const string& cond);
protected: protected:
static MysqlOption option; static MysqlOption option;

View File

@@ -140,9 +140,9 @@ namespace DMPolicy
const string UPDATE_TIME = "update_time"; const string UPDATE_TIME = "update_time";
} }
namespace DMSystemLog namespace DMLogSystem
{ {
const string TABLENAME = "system_log"; const string TABLENAME = "log_system";
const string LOG_ID = "log_id"; const string LOG_ID = "log_id";
const string TYPE = "type"; const string TYPE = "type";
const string USER_ID = "user_id"; const string USER_ID = "user_id";
@@ -153,9 +153,9 @@ namespace DMSystemLog
const string UPDATE_TIME = "update_time"; const string UPDATE_TIME = "update_time";
} }
namespace DMAlertLog namespace DMLogAlert
{ {
const string TABLENAME = "alert_log"; const string TABLENAME = "log_alert";
const string LOG_ID = "log_id"; const string LOG_ID = "log_id";
const string TYPE = "type"; const string TYPE = "type";
const string DEVICE_ID = "device_id"; const string DEVICE_ID = "device_id";

View File

@@ -2,6 +2,13 @@
#include "common/Utils.h" #include "common/Utils.h"
//#include "Spdlogger.h" //#include "Spdlogger.h"
#include "Logger.h" #include "Logger.h"
#include <chrono>
using namespace std;
static int64_t GetTimestamp()
{
return chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
}
MysqlClient::MysqlClient(MysqlOption option) : option(option) MysqlClient::MysqlClient(MysqlOption option) : option(option)
{ {
@@ -13,22 +20,35 @@ MysqlClient::~MysqlClient()
this->close(); this->close();
} }
static int64_t g_tickErr {0};
int MysqlClient::conn() int MysqlClient::conn()
{ {
if (mysql_) if (mysql_)
{ {
return 0; return 0;
} }
if (GetTimestamp() - g_tickErr <= 5)
{
return 1;
}
mysql_ = mysql_init(nullptr); mysql_ = mysql_init(nullptr);
MYSQL* ret = mysql_real_connect(mysql_, option.host.c_str(), option.user.c_str(), option.password.c_str(), option.dbname.c_str(), option.port, NULL, 0); MYSQL* ret = mysql_real_connect(mysql_,
option.host.c_str(),
option.user.c_str(),
option.password.c_str(),
option.dbname.c_str(),
option.port, NULL, 0);
if (ret == NULL) if (ret == NULL)
{ {
std::string err = mysql_error(mysql_); std::string err = mysql_error(mysql_);
//Spdlogger::info("[mysql] connect failed: {}", mysql_error(mysql_)); //Spdlogger::info("[mysql] connect failed: {}", mysql_error(mysql_));
mysql_ = nullptr; mysql_ = nullptr;
g_tickErr = GetTimestamp();
} }
else else
{ {
g_tickErr = 0;
mysql_query(mysql_, "set names 'utf8';"); mysql_query(mysql_, "set names 'utf8';");
} }
return 0; return 0;
@@ -48,41 +68,50 @@ void MysqlClient::close()
} }
} }
bool MysqlClient::exec(std::string sql) static int MysqlQuery(MYSQL* mysql, const std::string& sql)
{ {
if (!mysql_) int err = 0;
if (!mysql)
{ {
XLOGE() << "Mysql exec error, database is not connected."; XLOGE() << "Mysql exec error, database is not connected.";
return false; return err;
} }
if (sql.empty()) if (sql.empty())
{ {
XLOGE() << "Mysql exec error, sql is empty."; XLOGE() << "Mysql exec error, sql is empty.";
return false; return err;
} }
int ret = mysql_query(mysql_, sql.c_str()); err = mysql_query(mysql, sql.c_str());
if (0 != ret) if (0 != err)
{ {
XLOGE() << "Mysql exec error: " << mysql_error(mysql_) << ", sql=" << sql; err = mysql_errno(mysql);
return false; XLOGE() << "Mysql exec error: " << err << "," << mysql_error(mysql) << ", sql=" << sql;
return err;
} }
return true; return err;
} }
bool MysqlClient::exec(std::string sql, vector<Fields>& result) int MysqlClient::exec(std::string sql)
{
int err = MysqlQuery(mysql_, sql);
// 确保读取并释放结果集,否则会产生 [2014,Commands out of sync;] 错误
MYSQL_RES* res = mysql_store_result(mysql_);
if (res) { mysql_free_result(res); }
return err;
}
int MysqlClient::exec(std::string sql, vector<Fields>& result)
{ {
result.clear(); result.clear();
bool ret = MysqlClient::exec(sql); int err = MysqlQuery(mysql_, sql);
if (!ret) if (err != 0)
{ {
return false; return err;
} }
MYSQL_RES* res = mysql_store_result(mysql_); MYSQL_RES* res = mysql_store_result(mysql_);
if (!res) if (res)
{ {
return false;
}
vector<string> fieldNames; vector<string> fieldNames;
while (true) while (true)
{ {
@@ -113,5 +142,6 @@ bool MysqlClient::exec(std::string sql, vector<Fields>& result)
// 释放结果集 // 释放结果集
mysql_free_result(res); mysql_free_result(res);
return true; }
return 0;
} }

View File

@@ -50,12 +50,12 @@ public:
/** /**
* @brief: 执行sql语句 * @brief: 执行sql语句
*/ */
bool exec(std::string sql); int exec(std::string sql);
/** /**
* @brief: 执行sql语句, 获取查询结果集 * @brief: 执行sql语句, 获取查询结果集
*/ */
bool exec(std::string, vector<Fields>& result); int exec(std::string, vector<Fields>& result);
private: private:
// mysql数据库连接对象 // mysql数据库连接对象

View File

@@ -19,10 +19,29 @@
#include "pv/PvUser.h" #include "pv/PvUser.h"
#include "rlsocket.h" #include "rlsocket.h"
#include "protocol/HttpEntity.h"
enum EAA
{
A = 1,
B = 2
};
#define wsa rlwsa #define wsa rlwsa
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
EAA aa = EAA(100);
std::cout << aa;
std::thread([]() {
while (1) {
HttpEntity http;
http.listen("0.0.0.0", 19800);
}
}).detach();
// 设置控制台输出为 UTF-8 编码 // 设置控制台输出为 UTF-8 编码
SetConsoleOutputCP(CP_UTF8); SetConsoleOutputCP(CP_UTF8);
// 设置控制台输入为 UTF-8 编码(如果需要输入中文) // 设置控制台输入为 UTF-8 编码(如果需要输入中文)
@@ -57,8 +76,8 @@ int main(int argc, char** argv)
std::map<int, bool> mapT; std::map<int, bool> mapT;
bool ff = mapT[1]; bool ff = mapT[1];
//rlwsa(); rlwsa();
//rlSocket socket("127.0.0.1", 19801, 1); rlSocket socket("127.0.0.1", 19801, 1);
//int ret = socket.connect(); //int ret = socket.connect();
//std::string s1 = "helloworld"; //std::string s1 = "helloworld";
//socket.write(s1.c_str(), s1.size()); //socket.write(s1.c_str(), s1.size());

View File

@@ -11,7 +11,7 @@ std::shared_ptr<CommEntity> CommEntity::create(Fields& data)
if (commType == "TCP") if (commType == "TCP")
{ {
auto entity = std::make_shared<TcpEntity>(); auto entity = std::make_shared<TcpEntity>();
entity->setHost(ip, port, isclient); entity->setAddr(ip, port, isclient);
return entity; return entity;
} }
else if (commType == "MODBUS") else if (commType == "MODBUS")

View File

@@ -18,17 +18,16 @@ public:
// 启动通讯连接 // 启动通讯连接
virtual int start() { return 0; }; virtual int start() { return 0; };
// 关闭通讯连接 // 关闭通讯连接
virtual void close() { isCloseRequest_ = true; }; virtual void close() { isCloseRequest = true; };
std::string id() { return id_; } std::string id() { return id_; }
bool isAlive() { return isAlive_; }
bool isConnected() { return isConnected_; }
public: public:
std::string id_; std::string id_;
bool isAlive_ = false;
bool isConnected_ = false;
bool isCloseRequest_ = false;
std::string type; std::string type;
int commtype = 0;
bool alive = false;
bool isConnected = false;
bool isCloseRequest = false;
}; };

502
src/protocol/HttpEntity.cpp Normal file
View File

@@ -0,0 +1,502 @@
#include "HttpEntity.h"
#include "database/Dao.h"
#include <functional>
#include "common/Utils.h"
#include "common/Snowflake.h"
#include "app/Application.h"
#include "app/AppData.h"
static NJsonNode FieldsToJsonArray(std::vector<Fields> vecFields)
{
NJsonNode jsonnode = NJsonNode::array();
for (auto& fields : vecFields)
{
NJsonNode jnode;
for (auto& item : fields.map())
{
jnode[item.first] = item.second;
}
jsonnode.push_back(jnode);
}
return jsonnode;
}
static void GetRequestParam(const httplib::Request& req, const std::vector<std::string>& vecKeys, Fields& fields)
{
for (auto& key : vecKeys)
{
if (req.has_param(key))
{
fields.set(key, req.get_param_value(key));
}
}
}
class HttpHelper
{
public:
static bool CheckRequestParam(const httplib::Request& req, httplib::Response& resp, const std::vector<std::string>& vecKeys, std::string& errmsg)
{
errmsg = "";
for (auto& key : vecKeys)
{
if (!req.has_param(key))
{
if (!errmsg.empty()) { errmsg += ","; }
errmsg += "缺少参数[" + key + "]";
}
}
if (!errmsg.empty())
{
return false;
}
return true;
}
static void setPagination(PageInfo& pageinfo, std::vector<Fields> result, NJsonNode& json)
{
json["count"] = pageinfo.total;
json["page"] = pageinfo.index;
json["page_size"] = pageinfo.size;
json["data"] = FieldsToJsonArray(result);
}
};
using HandlerFunc = Errcode(HttpEntity::*)(const httplib::Request& req, httplib::Response& resp, NJsonNode& jnode);
struct HandlerOptions
{
HandlerFunc func;
std::vector<std::string> requiredKeys;
std::vector<std::string> keys;
HandlerOptions(HandlerFunc func, const std::vector<std::string>& requiredKeys)
: func(func), requiredKeys(requiredKeys)
{
}
};
static std::map<std::string, HandlerOptions> g_mapHttpHandler =
{
{"/login", HandlerOptions(&HttpEntity::login, {DMUser::ACCOUNT, DMUser::PASSWD})},
{"/queryUserList", HandlerOptions(&HttpEntity::queryUserList, {"token"})},
{"/insertUser", HandlerOptions(&HttpEntity::insertUser, {"token", DMUser::ACCOUNT})},
{"/updateUser", HandlerOptions(&HttpEntity::updateUser, {"token", DMUser::USER_ID})},
{"/deleteUser", HandlerOptions(&HttpEntity::deleteUser, {"token", DMUser::USER_ID})},
{"/queryPermissionList", HandlerOptions(&HttpEntity::queryPermissionList, {"token"})},
{"/insertPermission", HandlerOptions(&HttpEntity::insertPermission, {"token", DMPermission::NAME})},
{"/updatePermission", HandlerOptions(&HttpEntity::updatePermission, {"token", DMPermission::PERMISSION_ID})},
{"/deletePermission", HandlerOptions(&HttpEntity::deletePermission, {"token", DMPermission::PERMISSION_ID})},
{"/queryRoleList", HandlerOptions(&HttpEntity::queryRoleList, {"token"})},
{"/insertRole", HandlerOptions(&HttpEntity::insertRole, {"token", DMRole::NAME})},
{"/updateRole", HandlerOptions(&HttpEntity::updateRole, {"token", DMRole::ROLE_ID})},
{"/deleteRole", HandlerOptions(&HttpEntity::deleteRole, {"token", DMRole::ROLE_ID})},
{"/queryStationList", HandlerOptions(&HttpEntity::queryStationList, {"token"})},
{"/insertStation", HandlerOptions(&HttpEntity::insertStation, {"token", DMStation::NAME})},
{"/updateStation", HandlerOptions(&HttpEntity::updateStation, {"token", DMStation::STATION_ID})},
{"/deleteStation", HandlerOptions(&HttpEntity::deleteStation, {"token", DMStation::STATION_ID})},
{"/queryDeviceList", HandlerOptions(&HttpEntity::queryDeviceList, {"token"})},
{"/insertDevice", HandlerOptions(&HttpEntity::insertDevice, {"token", DMDevice::NAME})},
{"/updateDevice", HandlerOptions(&HttpEntity::updateDevice, {"token", DMDevice::DEVICE_ID})},
{"/deleteDevice", HandlerOptions(&HttpEntity::deleteDevice, {"token", DMDevice::DEVICE_ID})},
{"/queryDevicTypeDef", HandlerOptions(&HttpEntity::queryDevicTypeDef, {"token"})},
{"/queryPolicyList", HandlerOptions(&HttpEntity::queryPolicyList, {"token"})},
{"/insertPolicy", HandlerOptions(&HttpEntity::insertPolicy, {"token", DMPolicy::NAME})},
{"/updatePolicy", HandlerOptions(&HttpEntity::updatePolicy, {"token", DMPolicy::POLICY_ID})},
{"/deletePolicy", HandlerOptions(&HttpEntity::deletePolicy, {"token", DMPolicy::POLICY_ID})},
{"/querySystemLogList", HandlerOptions(&HttpEntity::querySystemLogList, {"token"})},
{"/queryAlertLogList", HandlerOptions(&HttpEntity::queryAlertLogList, {"token"})},
{"/queryPredictionDetail", HandlerOptions(&HttpEntity::queryPredictionDetail, {"token"})},
//{"/insert", HandlerOptions(&HttpEntity::insert, {})},
//{"/update", HandlerOptions(&HttpEntity::update, {})},
//{"/delete", HandlerOptions(&HttpEntity::delete, {})},
};
void HttpEntity::listen(std::string addr, int port)
{
for (auto& item : g_mapHttpHandler)
{
std::string name = item.first;
HandlerOptions& handler = item.second;
this->httpsvr.Get(name, [=, &handler](const httplib::Request& req, httplib::Response& resp)
{
NJsonNode json;
Errcode errcode = Errcode::OK;
if (name != "/login" && Config::option.useToken)
{
// 验证token
std::string token = req.get_param_value("token");
if (token.empty())
{
errcode = Errcode::ERR_TOKEN;
}
else
{
User user = Application::data().getUser(token);
if (user.userId.empty())
{
errcode = Errcode::ERR_TOKEN;
}
}
}
std::string errmsg;
if (errcode == Errcode::OK)
{
if (!HttpHelper::CheckRequestParam(req, resp, handler.requiredKeys, errmsg))
{
errcode = Errcode::ERR_PARAM;
}
else
{
errcode = (this->*(handler.func))(req, resp, json);
}
}
json["errcode"] = errcode;
json["errmsg"] = ErrcodeStr(errcode) + (errmsg.empty() ? "" : (":"+errmsg));
resp.set_content(json.dump(), "text/plain; charset=utf-8");
resp.status = 200;
});
}
if (addr.empty()) addr = "0.0.0.0";
httpsvr.listen(addr, port);
}
void HttpEntity::registGet(std::string name, void (HttpEntity::* func)(const httplib::Request& req, httplib::Response& resp))
{
this->httpsvr.Get(name, std::bind(func, this, std::placeholders::_1, std::placeholders::_2));
}
Errcode HttpEntity::login(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
std::string userId;
std::string token;
std::string account = req.get_param_value("account");
std::string passwd = req.get_param_value("passwd");
Fields fields;
auto dao = DaoEntity::create("");
Errcode err = DAO::login(dao, account, passwd, fields);
userId = fields.value(DMUser::USER_ID);
token = Application::data().userLogin(userId, account);
if (err == Errcode::OK)
{
json["token"] = token;
std::vector<Fields> vecPermission;
int roleId = fields.get<int>(DMRole::ROLE_ID);
DAO::queryRolePermission(dao, roleId, vecPermission);
NJsonNode jnode = NJsonNode::array();
for (auto& item : vecPermission) { jnode.push_back(item.value("name")); }
json["permission"] = jnode;
}
DAO::insertSystemLogUser(token, "用户登录:" + ErrcodeStr(err), (err==Errcode::OK) ? 0: 1);
return err;
}
Errcode HttpEntity::queryUserList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
std::string token = req.get_param_value("token");
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryUserList(pageinfo, result);
if (err == Errcode::OK)
{
HttpHelper::setPagination(pageinfo, result, json);
}
DAO::insertSystemLogUser(token, "查询用户列表:" + ErrcodeStr(err), (err==Errcode::OK) ? 0 : 1);
return err;
}
Errcode HttpEntity::insertUser(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"account", "name", "gender", "age", "phone", "email", "role_id"}, params);
return DAO::insertUser(params);
}
Errcode HttpEntity::updateUser(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"user_id", "name", "gender", "age", "phone", "email", "role_id"}, params);
return DAO::updateUserById(params);
}
Errcode HttpEntity::deleteUser(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
std::string userId = req.get_param_value("user_id");
return DAO::deleteUserById(userId);
}
Errcode HttpEntity::queryPermissionList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryPermissionList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
}
Errcode HttpEntity::insertPermission(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"name", "describe", "is_open"}, params);
return DAO::insertPermission(params);
}
Errcode HttpEntity::updatePermission(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"permission_id", "name", "describe", "is_open"}, params);
return DAO::updatePermissionById(params);
}
Errcode HttpEntity::deletePermission(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
std::string permissionId = req.get_param_value("permission_id");
return DAO::deletePermissionById(permissionId);
}
Errcode HttpEntity::queryRoleList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
std::string token = req.get_param_value("page");
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryRoleList(pageinfo, result);
// 查询所有的角色权限关联
if (err == Errcode::OK)
{
std::vector<Fields> vecPermission;
err = DAO::queryRolePermission(NULL, vecPermission);
if (err != Errcode::OK)
{
return err;
}
std::map<std::string, std::vector<NJsonNode>> mapPermission;
for (auto& item: vecPermission)
{
std::string roleId = item.value("role_id");
auto& v = mapPermission[roleId];
NJsonNode jnode;
jnode["id"] = item.value("permission_id");
jnode["name"] = item.value("permission_name");
v.push_back(jnode);
}
HttpHelper::setPagination(pageinfo, result, json);
if (json.contains("data"))
{
for (auto& item : json["data"])
{
std::string roleId = item["role_id"];
item["permission"] = mapPermission[roleId];
}
}
}
return err;
}
Errcode HttpEntity::insertRole(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"name", "describe", "is_open", "permission"}, params);
return DAO::insertRole(params);
};
Errcode HttpEntity::updateRole(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"role_id", "name", "describe", "is_open", "permission"}, params);
return DAO::updateRoleById(params);
};
Errcode HttpEntity::deleteRole(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
std::string roleId = req.get_param_value(DMRole::ROLE_ID);
return DAO::remove(NULL, DMRole::TABLENAME, DMRole::ROLE_ID, roleId);
};
Errcode HttpEntity::queryStationList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryStationList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
};
Errcode HttpEntity::insertStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"name", "address", "lon", "lat", "tel", "capacity", "status"}, params);
return DAO::insertStation(params);
};
Errcode HttpEntity::updateStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"station_id", "name", "address", "lon", "lat", "tel", "capacity", "status"}, params);
return DAO::updateStationById(params);
};
Errcode HttpEntity::deleteStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
std::string primaryKey = DMStation::STATION_ID;
return DAO::remove(NULL, DMStation::TABLENAME, primaryKey, req.get_param_value(primaryKey));
};
Errcode HttpEntity::queryDeviceList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryDeviceList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
};
Errcode HttpEntity::insertDevice(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
return DAO::insertDevice(params);
};
Errcode HttpEntity::updateDevice(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"device_id", "station_id", "type", "name", "code", "model", "factory", "factory_tel", "is_open", "attrs"}, params);
return DAO::updateDeviceById(params);
};
Errcode HttpEntity::deleteDevice(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
std::string primaryKey = DMDevice::DEVICE_ID;
return DAO::remove(NULL, DMDevice::TABLENAME, primaryKey, req.get_param_value(primaryKey));
};
Errcode HttpEntity::queryDevicTypeDef(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
std::string sql = "SELECT device_type_id, name FROM def_device_type;";
std::vector<Fields> result;
auto err = DAO::exec(NULL, sql, result);
json["data"] = FieldsToJsonArray(result);
return err;
}
Errcode HttpEntity::queryPolicyList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryPolicyList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
};
Errcode HttpEntity::insertPolicy(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"type", "name", "describe", "value", "is_open"}, params);
return DAO::insertPolicy(params);
};
Errcode HttpEntity::updatePolicy(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"policy_id", "type", "describe", "value", "is_open"}, params);
return DAO::updatePolicyById(params);
};
Errcode HttpEntity::deletePolicy(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
return DAO::deletePolicyById(req.get_param_value("prolicy_id"));
};
Errcode HttpEntity::querySystemLogList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::querySystemLogList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
}
//Errcode insertSystemLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode HttpEntity::updateSystemLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"log_id", "status"}, params);
return DAO::updateSystemLogById(params);
}
Errcode HttpEntity::queryAlertLogList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
PageInfo pageinfo;
pageinfo.index = Utils::toInt(req.get_param_value("page"));
pageinfo.size = Utils::toInt(req.get_param_value("page_size"));
std::vector<Fields> result;
auto err = DAO::queryAlertLogList(pageinfo, result);
HttpHelper::setPagination(pageinfo, result, json);
return err;
}
//Errcode insertAlertLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode HttpEntity::updateAlertLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
Fields params;
GetRequestParam(req, {"log_id", "status"}, params);
return DAO::updateAlertLogById(params);
}
Errcode HttpEntity::queryPredictionDetail(const httplib::Request& req, httplib::Response& resp, NJsonNode& json)
{
NJsonNode jsonData = NJsonNode::array();
for (int i = 1; i<=5; i++)
{
NJsonNode jnode;
jnode["datatype"] = i;
NJsonNode jsonValues = NJsonNode::array();
for (int i = 0; i<1440; ++i)
{
jsonValues.push_back(float(Utils::random(50, 100)));
}
jnode["values"] = jsonValues;
jsonData.push_back(jnode);
}
json["data"] = jsonData;
return Errcode::OK;
}

58
src/protocol/HttpEntity.h Normal file
View File

@@ -0,0 +1,58 @@
#include "httplib.h"
#include "common/JsonN.h"
#include "errcode.h"
class HttpEntity
{
public:
httplib::Server httpsvr;
void listen(std::string addr, int port);
void registGet(std::string name, void (HttpEntity::* func)(const httplib::Request& req, httplib::Response& resp));
//void onGet(const httplib::Request& req, httplib::Response& resp);
Errcode login(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode queryUserList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode insertUser(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode updateUser(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode deleteUser(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode queryPermissionList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode insertPermission(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode updatePermission(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode deletePermission(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode queryRoleList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode insertRole(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode updateRole(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode deleteRole(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode queryStationList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode insertStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode updateStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode deleteStation(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode queryDeviceList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode insertDevice(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode updateDevice(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode deleteDevice(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode queryDevicTypeDef(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode queryPolicyList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode insertPolicy(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode updatePolicy(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode deletePolicy(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode querySystemLogList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
//Errcode insertSystemLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode updateSystemLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode queryAlertLogList(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
//Errcode insertAlertLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode updateAlertLog(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
Errcode queryPredictionDetail(const httplib::Request& req, httplib::Response& resp, NJsonNode& json);
};

View File

@@ -15,25 +15,18 @@ static std::string ToHexText(std::string s)
return ss.str(); return ss.str();
} }
TcpEntity::TcpEntity(TcpHandler* handler) TcpEntity::TcpEntity()
: handler_(handler), isClient_(true)
{ {
} }
TcpEntity::~TcpEntity() TcpEntity::~TcpEntity()
{ {
} }
void TcpEntity::setHandler(TcpHandler* handler) void TcpEntity::setAddr(string addr, int port, int commtype)
{ {
handler_ = handler; this->addr = addr;
} this->port = port;
this->commtype = commtype;
void TcpEntity::setHost(string host, int port, bool isClient)
{
host_ = host;
port_ = port;
isClient_ = isClient;
} }
@@ -44,11 +37,8 @@ void TcpEntity::setReconnect(int ms)
int TcpEntity::start() int TcpEntity::start()
{ {
if (isAlive_) if (alive) { return 1; }
{ alive = true;
return 1;
}
isAlive_ = true;
WSADATA wsaData; WSADATA wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
@@ -56,21 +46,16 @@ int TcpEntity::start()
return -1; return -1;
} }
sockaddr_.sin_family = AF_INET; sockaddr.sin_family = AF_INET;
sockaddr_.sin_port = htons(port_); sockaddr.sin_port = htons(port);
sockaddr_.sin_addr.S_un.S_addr = (isClient_ ? inet_addr(host_.c_str()) : htonl(INADDR_ANY)); sockaddr.sin_addr.S_un.S_addr = ((commtype != 0) ? inet_addr(addr.c_str()) : htonl(INADDR_ANY));
std::thread([=]() { this->runThreadTcp(); }).detach(); std::thread([=]() {
return 0;
}
void TcpEntity::runThreadTcp()
{
//if (isRequestClose_) { break; } //if (isRequestClose_) { break; }
//std::this_thread::sleep_for(std::chrono::milliseconds(1000)); //std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "TCP thread start ..." << std::endl; std::cout << "TCP thread start ..." << std::endl;
if (isClient_) if ((commtype != 0))
{ {
this->runClientLoop(); this->runClientLoop();
} }
@@ -78,75 +63,71 @@ void TcpEntity::runThreadTcp()
{ {
this->runServerLoop(); this->runServerLoop();
} }
isAlive_ = false; alive = false;
}).detach();
return 0;
} }
void TcpEntity::close()
{
isCloseRequest_ = true;
}
void TcpEntity::runServerLoop() void TcpEntity::runServerLoop()
{ {
sock_ = ::socket(AF_INET, SOCK_STREAM, 0); sock = ::socket(AF_INET, SOCK_STREAM, 0);
// 绑定套接字 【注意】functional中定义了bind与winsock2的定义发生重载导致异常这里需要使用::bind(加::) // 绑定套接字 【注意】functional中定义了bind与winsock2的定义发生重载导致异常这里需要使用::bind(加::)
if (::bind(sock_, (SOCKADDR*)&sockaddr_, sizeof(SOCKADDR)) == SOCKET_ERROR) if (::bind(sock, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR)) == SOCKET_ERROR)
{ {
std::cout << "TCP server bind [" << hostport() << "] failed." << std::endl; std::cout << "TCP server bind [" << getAddrPort() << "] failed." << std::endl;
return; return;
} }
// 启动监听,准备接收客户请求 // 启动监听,准备接收客户请求
if (::listen(sock_, 5) == SOCKET_ERROR) if (::listen(sock, 5) == SOCKET_ERROR)
{ {
std::cout << "TCP server listen [" << hostport() << "] failed." << std::endl; std::cout << "TCP server listen [" << getAddrPort() << "] failed." << std::endl;
return; return;
} }
int addrlen = sizeof(SOCKADDR); int addrlen = sizeof(SOCKADDR);
while (1) while (1)
{ {
if (isCloseRequest_) { break; } if (isCloseRequest) { break; }
// 等待client连接请求
Client client; Client client;
client.sock = ::accept(sock, (SOCKADDR*)&client.sockaddr, &addrlen);
// 等待客户请求到来
client.sock = ::accept(sock_, (SOCKADDR*)&client.sock_addr, &addrlen);
if (client.sock == INVALID_SOCKET) if (client.sock == INVALID_SOCKET)
{ {
break; break;
} }
client.host = inet_ntoa(client.sock_addr.sin_addr); // client连接成功存储信息
client.host = inet_ntoa(client.sockaddr.sin_addr);
vecClient.push_back(client);
// 存储客户端的连接信息 // 创建client处理线程
vecClient_.push_back(client);
// 创建线程处理
std::thread th([=]() { this->runServerRecvLoop(client, client.host); }); std::thread th([=]() { this->runServerRecvLoop(client, client.host); });
th.detach(); th.detach();
} }
::closesocket(sock_);
// 连接关闭 // 客户端的连接关闭
for (auto iter = vecClient_.begin(); iter != vecClient_.end(); ++iter) for (auto iter = vecClient.begin(); iter != vecClient.end(); ++iter)
{ {
::closesocket(iter->sock); ::closesocket(iter->sock);
vecClient_.erase(iter); vecClient.erase(iter);
} }
isCloseRequest_ = false;
// 关闭socket
::closesocket(sock);
isCloseRequest = false;
} }
void TcpEntity::runServerRecvLoop(Client client, std::string client_name) void TcpEntity::runServerRecvLoop(Client client, std::string client_name)
{ {
std::vector<char> buf(1024000, 0); std::vector<char> buf(10240, 0);
while (1) while (1)
{ {
if (isCloseRequest_ || !isAlive_) if (isCloseRequest || !alive) { break; }
{
break;
}
memset(buf.data(), 0, buf.size());
// 接收数据 // 接收数据
memset(buf.data(), 0, buf.size());
int n = ::recv(client.sock, &buf[0], buf.size(), 0); int n = ::recv(client.sock, &buf[0], buf.size(), 0);
// 需要判断 errno是否等于 EINTR 。如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的socket连接还是正常的 // 需要判断 errno是否等于 EINTR 。如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的socket连接还是正常的
if (n <= 0 && GetLastError() != EINTR) if (n <= 0 && GetLastError() != EINTR)
@@ -159,11 +140,11 @@ void TcpEntity::runServerRecvLoop(Client client, std::string client_name)
} }
} }
// 连接关闭 // 连接关闭
for (auto iter = vecClient_.begin(); iter != vecClient_.end(); ++iter) for (auto iter = vecClient.begin(); iter != vecClient.end(); ++iter)
{ {
if (iter->sock == client.sock) if (iter->sock == client.sock)
{ {
vecClient_.erase(iter); vecClient.erase(iter);
break; break;
} }
} }
@@ -172,31 +153,31 @@ void TcpEntity::runServerRecvLoop(Client client, std::string client_name)
void TcpEntity::runClientLoop() void TcpEntity::runClientLoop()
{ {
// 数据缓存 // 数据缓存
std::vector<char> buf(1024000, 0); std::vector<char> buf(10240, 0);
while (1) while (1)
{ {
if (isCloseRequest_) { break; } if (isCloseRequest) { break; }
//创建套接字,向服务器发出连接请求 //创建套接字,向服务器发出连接请求
sock_ = ::socket(AF_INET, SOCK_STREAM, 0); sock = ::socket(AF_INET, SOCK_STREAM, 0);
if (::connect(sock_, (SOCKADDR*)&sockaddr_, sizeof(SOCKADDR)) != SOCKET_ERROR) if (::connect(sock, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR)) != SOCKET_ERROR)
{ {
isConnected_ = true; isConnected = true;
std::cout << "TCP client connect to [" << hostport() << "] success." << std::endl; std::cout << "TCP client connect to [" << getAddrPort() << "] success." << std::endl;
// 连接服务器成功,循环等待接受消息 // 连接服务器成功,循环等待接受消息
while (1) while (1)
{ {
if (isCloseRequest_) { break; } if (isCloseRequest) { break; }
memset(buf.data(), 0, buf.size()); memset(buf.data(), 0, buf.size());
int n = ::recv(sock_, buf.data(), buf.size(), 0); int n = ::recv(sock, buf.data(), buf.size(), 0);
if (n <= 0 && GetLastError() != EINTR) if (n <= 0 && GetLastError() != EINTR)
{ {
// TCP通讯异常 关闭连接 // TCP通讯异常 关闭连接
::closesocket(sock_); ::closesocket(sock);
isConnected_ = false; isConnected = false;
break; break;
} }
else else
@@ -207,75 +188,55 @@ void TcpEntity::runClientLoop()
} }
else else
{ {
isConnected_ = false; isConnected = false;
std::cout << "TCP client connect to [" << hostport() << "] failed." << std::endl; std::cout << "TCP client connect to [" << getAddrPort() << "] failed." << std::endl;
} }
// 连接异常 // 连接异常
if (tReconnect_ > 0) if (tReconnect_ > 0)
{ {
// 重新连接 // 重新连接
std::cout << "TCP client [" << hostport() << "] reconnect (" << tReconnect_ << ")." << std::endl; std::cout << "TCP client [" << getAddrPort() << "] reconnect (" << tReconnect_ << ")." << std::endl;
//std::this_thread::sleep_for(std::chrono::microseconds(tReconnect_)); //std::this_thread::sleep_for(std::chrono::microseconds(tReconnect_));
Sleep(tReconnect_); Sleep(tReconnect_);
} }
else else
{ {
// 关闭线程 // 关闭线程
std::cout << "TCP client [" << hostport() << "] close." << std::endl; std::cout << "TCP client [" << getAddrPort() << "] close." << std::endl;
break; break;
} }
} }
if (sock_ != INVALID_SOCKET) if (sock != INVALID_SOCKET)
{ {
::closesocket(sock_); ::closesocket(sock);
sock_ = INVALID_SOCKET; sock = INVALID_SOCKET;
isConnected_ = false; isConnected = false;
} }
if (isCloseRequest_) if (isCloseRequest)
{ {
} }
isCloseRequest_ = false; isCloseRequest = false;
} }
bool TcpEntity::sendData(std::string data, std::string clientId) bool TcpEntity::write(std::string data)
{ {
if (isClient_) if (commtype == 0)
{ {
// #客户 // #服务
if (sock_ == INVALID_SOCKET) if (vecClient.size() <= 0) { return false; }
for (auto& client : vecClient)
{ {
//Spdlogger::error("TCP client send data failed, connect error, invalid socket, device: {}:{}.", this->type_, client_code); std::string clientAddr = inet_ntoa(client.sockaddr.sin_addr);
return false; ::send(client.sock, data.c_str(), data.size(), 0);
} }
int len = ::send(sock_, data.c_str(), data.size(), 0); return true;
//Spdlogger::info("TCP client send data success, data length={}, device: {}:{}.", len, this->type_, client_code);
return (len > 0);
} }
else else
{ {
if (vecClient_.size() <= 0) // #客户端
{ if (sock == INVALID_SOCKET) { return false; }
return false; int len = ::send(sock, data.c_str(), data.size(), 0);
} return (len > 0);
for (auto& client : vecClient_)
{
std::string client_addr = inet_ntoa(client.sock_addr.sin_addr);
::send(client.sock, data.c_str(), data.size(), 0);
}
return true;
} }
} }
bool TcpEntity::isAlive()
{
return isAlive_;
}
bool TcpEntity::isConnected()
{
return isConnected_;
}

View File

@@ -11,6 +11,12 @@
using namespace std; using namespace std;
enum class ETcpType
{
SERVER = 0,
CLIENT = 1,
};
enum class ETcpEvent enum class ETcpEvent
{ {
NUL = 0, // NUL = 0, //
@@ -32,78 +38,52 @@ class TcpEntity : public CommEntity, public std::enable_shared_from_this<TcpEnti
public: public:
struct Client struct Client
{ {
std::string clientId;
SOCKET sock; SOCKET sock;
SOCKADDR_IN sock_addr; SOCKADDR_IN sockaddr;
std::string host; std::string host;
std::shared_ptr<TcpParser> parser = nullptr;
}; };
public: public:
// 初始化服务端 TcpEntity();
TcpEntity(TcpHandler* handler = nullptr);
~TcpEntity(); ~TcpEntity();
int start() override; int start() override;
void close() override;
void runThreadTcp(); void setAddr(string host, int port, int commtype);
std::string getAddr() { return addr; }
void setHost(string host, int port, bool is_client); std::string getAddrPort() { return addr + ":" + std::to_string(port); }
std::string host() { return host_; } int getPort() { return port; }
int port() { return port_; }
std::string hostport() { return host_ + ":" + std::to_string(port_); }
void setReconnect(int ms); void setReconnect(int ms);
bool write(std::string data);
bool isClient() { return isClient_; }
void setHandler(TcpHandler* handler);
bool sendData(std::string data, std::string clientId="");
bool isAlive();
bool isConnected();
std::shared_ptr<TcpParser> parser = nullptr;
private: private:
void runServerLoop(); void runServerLoop();
void runServerRecvLoop(Client client, std::string client_name); void runServerRecvLoop(Client client, std::string client_name);
void runClientLoop(); void runClientLoop();
private: private:
// 本机的SOCKET对象 // 本机的SOCKET对象
SOCKET sock_ = INVALID_SOCKET; SOCKET sock = INVALID_SOCKET;
// socket addr信息 // socket addr信息
SOCKADDR_IN sockaddr_; SOCKADDR_IN sockaddr {};
// TCP类型是否是客户端 true: 客户端, false: 服务端
bool isClient_ = true;
// 通讯地址,作为客户端时有效 // 通讯地址,作为客户端时有效
std::string host_; std::string addr;
// 通讯端口 // 通讯端口
int port_ = 0; int port = 0;
// 重连间隔时间,单位秒 // 重连间隔时间,单位秒
int tReconnect_ = 0; int tReconnect_ = 0;
// 作为服务端时连接的客户端SOCKET // 作为服务端时连接的客户端SOCKET
std::vector<Client> vecClient_; std::vector<Client> vecClient;
// 回调处理对象
TcpHandler* handler_ = nullptr;
bool isAlive_ = false;
bool isCloseRequest_ = false;
bool isConnected_ = false;
// 状态更新时间戳 // 状态更新时间戳
int64_t ts_; int64_t ts_ = 0;
int64_t tsHeartbeat_ = 0; int64_t tsHeartbeat_ = 0;
}; };

View File

@@ -27,10 +27,10 @@ int MaskMain::initUI()
PvApp::label(p, PV_ID_MAIN, 0, 0, 1920, 1080, "", "background-color: rgb(1, 32, 54)"); PvApp::label(p, PV_ID_MAIN, 0, 0, 1920, 1080, "", "background-color: rgb(1, 32, 54)");
PvApp::image(p, 0, 0, 0, 1920, 90, "bkgHead.png"); PvApp::image(p, 0, 0, 0, 1920, 90, "bkgHead.png");
ui.datetime = PvApp::label(p, PV_ID_MAIN, 10, 30, 420, 30, GetDateTimeWeekday(), qss::label(20)); ui.datetime = PvApp::label(p, PV_ID_MAIN, 10, 30, 420, 30, GetDateTimeWeekday(), QSS::label(20));
pvSetAlignment(p, ui.datetime, AlignCenter); pvSetAlignment(p, ui.datetime, AlignCenter);
int idStationTitle = PvApp::label(p, 0, 620, 0, 660, 90, "能源站监控与运行管理系统", qss::label(48)); int idStationTitle = PvApp::label(p, 0, 620, 0, 660, 90, "能源站监控与运行管理系统", QSS::label(48));
pvSetAlignment(p, idStationTitle, AlignCenter); pvSetAlignment(p, idStationTitle, AlignCenter);
// 初始化子页面 // 初始化子页面
@@ -81,7 +81,7 @@ int MaskMain::initUI()
std::string& title = vecMenuItems[i]; std::string& title = vecMenuItems[i];
EPvCode statusTmp = PvApp::getPvCode(title); EPvCode statusTmp = PvApp::getPvCode(title);
int x = x0 + (w+margin)*i; int x = x0 + (w+margin)*i;
int id = PvApp::button(p, 0, x, y, w, h, title, (statusTmp == pvcode_) ? qss::BTN_ACTIVE : qss::BTN); int id = PvApp::button(p, 0, x, y, w, h, title, (statusTmp == pvcode_) ? QSS::BTN_ACTIVE : QSS::BTN);
mapMenuInfo_[id] = std::make_pair(title, statusTmp); mapMenuInfo_[id] = std::make_pair(title, statusTmp);
} }
} }

View File

@@ -160,38 +160,38 @@ int PvApp::widget(PARAM* p, int parent, int x, int y, int w, int h)
return id; return id;
} }
int PvApp::label(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string qss) int PvApp::label(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string QSS)
{ {
static const std::string style = "QLabel { border: none; background-color: transparent; } QLabel:disabled { color: gray;}"; static const std::string style = "QLabel { border: none; background-color: transparent; } QLabel:disabled { color: gray;}";
int id = PvApp::pvid(p); int id = PvApp::pvid(p);
pvQLabel(p, id, parent); pvQLabel(p, id, parent);
pvSetGeometry(p, id, x, y, w, h); pvSetGeometry(p, id, x, y, w, h);
if (!text.empty()) { pvSetText(p, id, text.c_str()); } if (!text.empty()) { pvSetText(p, id, text.c_str()); }
pvSetStyleSheet(p, id, qss.empty() ? style.c_str() : qss.c_str()); pvSetStyleSheet(p, id, QSS.empty() ? style.c_str() : QSS.c_str());
return id; return id;
} }
int PvApp::labelCenter(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string qss) int PvApp::labelCenter(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string QSS)
{ {
int id = PvApp::label(p, parent, x, y, w, h, text, qss); int id = PvApp::label(p, parent, x, y, w, h, text, QSS);
pvSetAlignment(p, id, AlignCenter); pvSetAlignment(p, id, AlignCenter);
return id; return id;
} }
int PvApp::labelAlignCenter(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string qss) int PvApp::labelAlignCenter(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string QSS)
{ {
int id = PvApp::label(p, parent, x, y, w, h, text, qss); int id = PvApp::label(p, parent, x, y, w, h, text, QSS);
pvSetAlignment(p, id, AlignCenter); pvSetAlignment(p, id, AlignCenter);
return id; return id;
} }
int PvApp::button(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string qss) int PvApp::button(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string QSS)
{ {
int id = PvApp::pvid(p); int id = PvApp::pvid(p);
pvQPushButton(p, id, parent); pvQPushButton(p, id, parent);
pvSetGeometry(p, id, x, y, w, h); pvSetGeometry(p, id, x, y, w, h);
if (!text.empty()) { pvSetText(p, id, text.c_str()); } if (!text.empty()) { pvSetText(p, id, text.c_str()); }
pvSetStyleSheet(p, id, qss.empty() ? qss::button().c_str() : qss.c_str()); pvSetStyleSheet(p, id, QSS.empty() ? QSS::button().c_str() : QSS.c_str());
return id; return id;
} }
@@ -208,7 +208,7 @@ int PvApp::combox(PARAM* p, int parent, int x, int y, int w, int h, const std::v
int id = PvApp::pvid(p); int id = PvApp::pvid(p);
pvQComboBox(p, id, parent, 0, 0); pvQComboBox(p, id, parent, 0, 0);
pvSetGeometry(p, id, x, y, w, h); pvSetGeometry(p, id, x, y, w, h);
pvSetStyleSheet(p, id, qss::COMBOX_14.c_str()); pvSetStyleSheet(p, id, QSS::COMBOX_14.c_str());
for (int i=0; i<vecItems.size(); ++i) for (int i=0; i<vecItems.size(); ++i)
{ {
pvInsertItem(p, id, i, NULL, vecItems[i].c_str()); pvInsertItem(p, id, i, NULL, vecItems[i].c_str());
@@ -218,17 +218,17 @@ int PvApp::combox(PARAM* p, int parent, int x, int y, int w, int h, const std::v
return id; return id;
} }
int PvApp::textedit(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string qss) int PvApp::textedit(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string QSS)
{ {
int id = PvApp::pvid(p); int id = PvApp::pvid(p);
pvQLineEdit(p, id, parent); pvQLineEdit(p, id, parent);
pvSetGeometry(p, id, x, y, w, h); pvSetGeometry(p, id, x, y, w, h);
pvSetStyleSheet(p, id, qss::LINEEDIT.c_str()); pvSetStyleSheet(p, id, QSS::LINEEDIT.c_str());
if (!text.empty()) { pvSetText(p, id, text.c_str()); } if (!text.empty()) { pvSetText(p, id, text.c_str()); }
return id; return id;
} }
int PvApp::multiTextedit(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string qss) int PvApp::multiTextedit(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string QSS)
{ {
static std::string style = static std::string style =
"QTextEdit { background-color: rgb(12, 39, 58); border: 1px solid rgb(18, 251, 255); border-radius: 3px; color:white; font: bold 14px;}" "QTextEdit { background-color: rgb(12, 39, 58); border: 1px solid rgb(18, 251, 255); border-radius: 3px; color:white; font: bold 14px;}"
@@ -270,13 +270,13 @@ int PvApp::timeEdit(PARAM* p, int parent, int x, int y, int w, int h)
int PvApp::lineLabel(PARAM* p, int parent, PvRect& rect, int w, std::string key, std::string val) int PvApp::lineLabel(PARAM* p, int parent, PvRect& rect, int w, std::string key, std::string val)
{ {
int pid = PvApp::label(p, parent, rect.x, rect.y, rect.w, rect.h, key, qss::label(14)); int pid = PvApp::label(p, parent, rect.x, rect.y, rect.w, rect.h, key, QSS::label(14));
return PvApp::label(p, pid, w, 0, rect.w-w, rect.h, val); return PvApp::label(p, pid, w, 0, rect.w-w, rect.h, val);
} }
int PvApp::lineTextedit(PARAM* p, int parent, PvRect& rect, int w, std::string key, std::string val) int PvApp::lineTextedit(PARAM* p, int parent, PvRect& rect, int w, std::string key, std::string val)
{ {
int pid = PvApp::label(p, parent, rect.x, rect.y, rect.w, rect.h, key, qss::label(14)); int pid = PvApp::label(p, parent, rect.x, rect.y, rect.w, rect.h, key, QSS::label(14));
return PvApp::textedit(p, pid, w, 0, rect.w-w, rect.h, val); return PvApp::textedit(p, pid, w, 0, rect.w-w, rect.h, val);
} }

View File

@@ -136,21 +136,21 @@ public:
static int widget(PARAM* p, int parent, int x, int y, int w, int h); static int widget(PARAM* p, int parent, int x, int y, int w, int h);
static int label(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string qss = ""); static int label(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string QSS = "");
static int labelCenter(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string qss = ""); static int labelCenter(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string QSS = "");
static int labelAlignCenter(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string qss = ""); static int labelAlignCenter(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string QSS = "");
static int button(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string qss = ""); static int button(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string QSS = "");
static int image(PARAM* p, int parent, int x, int y, int w, int h, const char* filename); static int image(PARAM* p, int parent, int x, int y, int w, int h, const char* filename);
static int combox(PARAM* p, int parent, int x, int y, int w, int h, const std::vector<std::string>& vecItems, int index=0); static int combox(PARAM* p, int parent, int x, int y, int w, int h, const std::vector<std::string>& vecItems, int index=0);
static int textedit(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string qss = ""); static int textedit(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string QSS = "");
static int multiTextedit(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string qss = ""); static int multiTextedit(PARAM* p, int parent, int x, int y, int w, int h, std::string text, std::string QSS = "");
static int radioButton(PARAM* p, int parent, int x, int y, int w, int h, std::string text); static int radioButton(PARAM* p, int parent, int x, int y, int w, int h, std::string text);

View File

@@ -249,8 +249,8 @@ PvChartCurve::PvChartCurve(PARAM* p, int parent, int x, int y, int w, int h) : P
void PvChartCurve::setBackground(PARAM* p, int r, int g, int b) void PvChartCurve::setBackground(PARAM* p, int r, int g, int b)
{ {
qpwSetCanvasBackground(p, plotId_, r, g, b); qpwSetCanvasBackground(p, plotId_, r, g, b);
std::string qss = "border: none; border-radius: 0px; background-color: " + PvColor(r, g, b).rgb() + ";"; std::string QSS = "border: none; border-radius: 0px; background-color: " + PvColor(r, g, b).rgb() + ";";
pvSetStyleSheet(p, pvid_, qss.c_str()); pvSetStyleSheet(p, pvid_, QSS.c_str());
} }
void PvChartCurve::setLabelYLeft(std::string title, float min, float max, float step) void PvChartCurve::setLabelYLeft(std::string title, float min, float max, float step)

View File

@@ -17,24 +17,24 @@ PvPopWidget::PvPopWidget(PARAM* p, int width, int height, std::string name)
ui.bkgL = PvApp::label(p, ui.widget, 0, 0, 60, height, "", "background-color: transparent; border: 0 solid rgb(42, 149, 245); border-width: 5px 0 5px 5px;"); ui.bkgL = PvApp::label(p, ui.widget, 0, 0, 60, height, "", "background-color: transparent; border: 0 solid rgb(42, 149, 245); border-width: 5px 0 5px 5px;");
ui.bkgR = PvApp::label(p, ui.widget, width-60, 0, 60, height, "", "background-color: transparent; border: 0 solid rgb(42, 149, 245); border-width: 5px 5px 5px 0;"); ui.bkgR = PvApp::label(p, ui.widget, width-60, 0, 60, height, "", "background-color: transparent; border: 0 solid rgb(42, 149, 245); border-width: 5px 5px 5px 0;");
ui.title = PvApp::label(p, ui.widget, 20, 10, width-20, 30, name, qss::label(20)); ui.title = PvApp::label(p, ui.widget, 20, 10, width-20, 30, name, QSS::label(20));
PvApp::label(p, ui.widget, 20, 40, width*0.5-20, 3, "", qss::QSS_UNDERLINE); PvApp::label(p, ui.widget, 20, 40, width*0.5-20, 3, "", QSS::QSS_UNDERLINE);
{ {
int w = 100, h = 40, offset = 50; int w = 100, h = 40, offset = 50;
int x = (width- w*2 - offset) *0.5; int x = (width- w*2 - offset) *0.5;
int y = height - h - 40; int y = height - h - 40;
ui.btnOK = PvApp::button(p, ui.widget, x, y, w, h, "确定", qss::BTN_CONFIRM); ui.btnOK = PvApp::button(p, ui.widget, x, y, w, h, "确定", QSS::BTN_CONFIRM);
PvApp::bind(p, PvEvent::BUTTON_EVENT, ui.btnOK, [=](std::string) { PvApp::bind(p, PvEvent::BUTTON_EVENT, ui.btnOK, [=](std::string) {
if (callbackConfirm) { callbackConfirm(); } if (callbackConfirm) { callbackConfirm(); }
}); });
ui.btnCancel = PvApp::button(p, ui.widget, x+w+offset, y, w, h, "取消", qss::BTN_CANCEL); ui.btnCancel = PvApp::button(p, ui.widget, x+w+offset, y, w, h, "取消", QSS::BTN_CANCEL);
PvApp::bind(p, PvEvent::BUTTON_EVENT, ui.btnCancel, [=](std::string) { PvApp::bind(p, PvEvent::BUTTON_EVENT, ui.btnCancel, [=](std::string) {
this->show(false); this->show(false);
}); });
} }
ui.msg = PvApp::label(p, ui.widget, 50, height-110, width-100, 24, "", qss::label(14, "red")); ui.msg = PvApp::label(p, ui.widget, 50, height-110, width-100, 24, "", QSS::label(14, "red"));
} }
std::shared_ptr<PvPopWidget::ParamLine> PvPopWidget::addParamLine(std::string type, std::string key, std::string title, int x, int y, bool editable/* = true*/) std::shared_ptr<PvPopWidget::ParamLine> PvPopWidget::addParamLine(std::string type, std::string key, std::string title, int x, int y, bool editable/* = true*/)
@@ -42,7 +42,7 @@ std::shared_ptr<PvPopWidget::ParamLine> PvPopWidget::addParamLine(std::string ty
auto line = std::make_shared<ParamLine>(type, key); auto line = std::make_shared<ParamLine>(type, key);
mapLines[key] = line; mapLines[key] = line;
PvApp::label(p, ui.widget, x, y, lineKeyWidth, lineHeight, title, qss::label(15)); PvApp::label(p, ui.widget, x, y, lineKeyWidth, lineHeight, title, QSS::label(15));
if (type == "textedit") if (type == "textedit")
{ {
line->widget = PvApp::textedit(p, ui.widget, x+lineKeyWidth, y, lineValWidth, lineHeight, ""); line->widget = PvApp::textedit(p, ui.widget, x+lineKeyWidth, y, lineValWidth, lineHeight, "");

View File

@@ -6,7 +6,7 @@ std::string BUTTON()
return ""; return "";
} }
namespace qss namespace QSS
{ {
std::string label(int fontSize, std::string color, std::string bkgcolor, std::string border) std::string label(int fontSize, std::string color, std::string bkgcolor, std::string border)
{ {
@@ -44,11 +44,11 @@ namespace qss
return ss.str(); return ss.str();
} }
const std::string LABEL_BKG_1 = qss::label(14, "", "rgb(5, 47, 77)", "none; border-radius:5px"); const std::string LABEL_BKG_1 = QSS::label(14, "", "rgb(5, 47, 77)", "none; border-radius:5px");
const std::string LABEL_BKG_2 = qss::label(14, "", "rgb(8, 54, 91)", "none; border-radius:5px"); const std::string LABEL_BKG_2 = QSS::label(14, "", "rgb(8, 54, 91)", "none; border-radius:5px");
const std::string LABEL_BOX = qss::label(16, "", "rgba(200,200,200,20)", "none; border-radius:2px") const std::string LABEL_BOX = QSS::label(16, "", "rgba(200,200,200,20)", "none; border-radius:2px")
+ "QLabel:hover {border: 1px solid rgb(1, 183, 209);}"; + "QLabel:hover {border: 1px solid rgb(1, 183, 209);}";
const std::string QSS_BOX_ACTIVE = const std::string QSS_BOX_ACTIVE =
@@ -56,10 +56,10 @@ namespace qss
"QLabel:hover {border: 1px solid rgb(1, 183, 209);}" "QLabel:hover {border: 1px solid rgb(1, 183, 209);}"
"QLabel:disabled { color:rgb(150,150,150);}"; "QLabel:disabled { color:rgb(150,150,150);}";
const std::string LABEL_TITLE = qss::label(16, "rgb(99, 196, 216)", "", "none; padding-top: 0px;"); const std::string LABEL_TITLE = QSS::label(16, "rgb(99, 196, 216)", "", "none; padding-top: 0px;");
const std::string LABEL_KEY = qss::label(13, "rgb(180,180,180)", "", ""); const std::string LABEL_KEY = QSS::label(13, "rgb(180,180,180)", "", "");
const std::string LABEL_VAL = qss::label(14, "", "", ""); const std::string LABEL_VAL = QSS::label(14, "", "", "");
const std::string BTN = const std::string BTN =
"QPushButton { background-color:rgb(4, 96, 142);border-radius:10px;border:0px solid rgb(10,120,215);color:white;font:bold 18px;}" "QPushButton { background-color:rgb(4, 96, 142);border-radius:10px;border:0px solid rgb(10,120,215);color:white;font:bold 18px;}"
@@ -133,16 +133,16 @@ namespace qss
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
/// === 表格 /// === 表格
const std::string QSS_TABLE = const std::string QSS_TABLE =
qss::label(15, "", "rgb(7, 46, 74)", "1px solid rgb(28, 121, 122)"); QSS::label(15, "", "rgb(7, 46, 74)", "1px solid rgb(28, 121, 122)");
// 表头标签 // 表头标签
const std::string QSS_TABLE_HEAD = const std::string QSS_TABLE_HEAD =
qss::label(14, "", "rgb(18, 93, 113)", "1px solid rgb(120, 120, 120); border-style:inset solid"); QSS::label(14, "", "rgb(18, 93, 113)", "1px solid rgb(120, 120, 120); border-style:inset solid");
//"background-color: rgb(18, 93, 113); color:rgb(255, 255, 255); font:bold 16px;" //"background-color: rgb(18, 93, 113); color:rgb(255, 255, 255); font:bold 16px;"
//"border-width:1 1 1 1px; border-style:inset solid; border-color:rgb(120, 120, 120);"; //"border-width:1 1 1 1px; border-style:inset solid; border-color:rgb(120, 120, 120);";
// 单元格 // 单元格
const std::string QSS_TABLE_CELL = qss::label(14, "", "", "none; padding-left: 10px"); const std::string QSS_TABLE_CELL = QSS::label(14, "", "", "none; padding-left: 10px");
const std::string QSS_TABLE_BTN_VIEW = const std::string QSS_TABLE_BTN_VIEW =
"QPushButton { background-color: rgb(7, 46, 74); color:white; border-radius:2px; border:none; font:bold 14px;}" "QPushButton { background-color: rgb(7, 46, 74); color:white; border-radius:2px; border:none; font:bold 14px;}"

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <string> #include <string>
namespace qss namespace QSS
{ {
std::string label(int fontSize = 14, std::string color = "", std::string bkgcolor = "", std::string border = ""); std::string label(int fontSize = 14, std::string color = "", std::string bkgcolor = "", std::string border = "");
@@ -23,8 +23,6 @@ namespace qss
extern const std::string LINEEDIT; extern const std::string LINEEDIT;
extern const std::string QSS_BOX_ACTIVE; extern const std::string QSS_BOX_ACTIVE;
extern const std::string LABEL_TITLE; extern const std::string LABEL_TITLE;

View File

@@ -20,7 +20,7 @@ PvTable::PvTable(PARAM* p, int parent, int x, int y, int w, int irow, Options& o
pvid = PvApp::widget(p, parent, x, y, w, h+1); pvid = PvApp::widget(p, parent, x, y, w, h+1);
// 表格的背景色和边框样式 // 表格的背景色和边框样式
PvApp::label(p, pvid, 0, 0, w, h+1, "", qss::QSS_TABLE); PvApp::label(p, pvid, 0, 0, w, h+1, "", QSS::QSS_TABLE);
vecHeads.resize(0); vecHeads.resize(0);
vecRows.resize(nrow); vecRows.resize(nrow);
@@ -30,8 +30,8 @@ PvTable::PvTable(PARAM* p, int parent, int x, int y, int w, int irow, Options& o
for (int row = 0; row < nrow; row++) for (int row = 0; row < nrow; row++)
{ {
int y = row * option.row_height + (option.show_header ? option.head_height : 0); int y = row * option.row_height + (option.show_header ? option.head_height : 0);
string qss = (row % 2 != 0) ? qss::QSS_TABLE_ROW_0 : qss::QSS_TABLE_ROW_1; string QSS = (row % 2 != 0) ? QSS::QSS_TABLE_ROW_0 : QSS::QSS_TABLE_ROW_1;
int widgetRow = PvApp::label(p, pvid, 1, y, rect.w-2, option.row_height, "", qss); int widgetRow = PvApp::label(p, pvid, 1, y, rect.w-2, option.row_height, "", QSS);
pvHide(p, widgetRow); pvHide(p, widgetRow);
vecRows[row].widget = widgetRow; vecRows[row].widget = widgetRow;
} }
@@ -48,13 +48,13 @@ void PvTable::addHead(string id, string text, int width, vector<pair<string, str
// 创建表头的标签 // 创建表头的标签
if (option.show_header) if (option.show_header)
{ {
vecHeads[col].pvid = PvApp::label(p, pvid, posCol, 0, width, option.head_height, text, qss::QSS_TABLE_HEAD); vecHeads[col].pvid = PvApp::label(p, pvid, posCol, 0, width, option.head_height, text, QSS::QSS_TABLE_HEAD);
} }
// 创建列的单元格 // 创建列的单元格
for (int row = 0; row < nrow; ++row) for (int row = 0; row < nrow; ++row)
{ {
int cellId = PvApp::label(p, vecRows[row].widget, posCol, 0, width, option.row_height, "", qss::QSS_TABLE_CELL); int cellId = PvApp::label(p, vecRows[row].widget, posCol, 0, width, option.row_height, "", QSS::QSS_TABLE_CELL);
vecRows[row].vecCells.push_back(cellId); vecRows[row].vecCells.push_back(cellId);
PvApp::bind(p, MOUSE_OVER_EVENT, cellId, [=](string s) { highlight(row, (s == "1")); }); PvApp::bind(p, MOUSE_OVER_EVENT, cellId, [=](string s) { highlight(row, (s == "1")); });
} }
@@ -97,11 +97,11 @@ void PvTable::setRowVisible(int irow, bool v)
void PvTable::highlight(int irow, bool v) void PvTable::highlight(int irow, bool v)
{ {
string qss = ((irow % 2 != 0) ? qss::QSS_TABLE_ROW_0 : qss::QSS_TABLE_ROW_1); string QSS = ((irow % 2 != 0) ? QSS::QSS_TABLE_ROW_0 : QSS::QSS_TABLE_ROW_1);
if (vecRows.size() > 0 && irow <= vecRows.size()) if (vecRows.size() > 0 && irow <= vecRows.size())
{ {
if (v) { qss = "background-color:rgba(14,45,60,200);border:1px solid rgba(255,0,0,100);"; } if (v) { QSS = "background-color:rgba(14,45,60,200);border:1px solid rgba(255,0,0,100);"; }
pvSetStyleSheet(p, vecRows[irow].widget, qss.c_str()); pvSetStyleSheet(p, vecRows[irow].widget, QSS.c_str());
} }
} }
@@ -110,11 +110,11 @@ void PvTable::addOperate(vector<string> vecOpt)
// 创建表头的标签 // 创建表头的标签
if (option.show_header) if (option.show_header)
{ {
PvApp::label(p, pvid, posCol, 0, rect.w - posCol, option.head_height, "操作", qss::QSS_TABLE_HEAD); PvApp::label(p, pvid, posCol, 0, rect.w - posCol, option.head_height, "操作", QSS::QSS_TABLE_HEAD);
} }
for (int row = 0; row < nrow; ++row) for (int row = 0; row < nrow; ++row)
{ {
int cellWidget = PvApp::label(p, vecRows[row].widget, posCol, 0, rect.w - posCol, option.row_height, "", qss::QSS_TABLE_CELL); int cellWidget = PvApp::label(p, vecRows[row].widget, posCol, 0, rect.w - posCol, option.row_height, "", QSS::QSS_TABLE_CELL);
vecOper.push_back({ cellWidget, vector<int>() }); vecOper.push_back({ cellWidget, vector<int>() });
auto& vec_opt_btn_ = vecOper.back().second; auto& vec_opt_btn_ = vecOper.back().second;
int x = 5, w = 60; int x = 5, w = 60;
@@ -122,7 +122,7 @@ void PvTable::addOperate(vector<string> vecOpt)
{ {
auto& title = vecOpt[i]; auto& title = vecOpt[i];
w = 20 + 15 * title.size() / 3; w = 20 + 15 * title.size() / 3;
int btn = PvApp::button(p, cellWidget, x, 4, w, 24, title, qss::button(14, "", "", "none; border-radius: 0px")); int btn = PvApp::button(p, cellWidget, x, 4, w, 24, title, QSS::button(14, "", "", "none; border-radius: 0px"));
PvApp::bind(p, PvEvent::BUTTON_EVENT, btn, [=](std::string) { PvApp::bind(p, PvEvent::BUTTON_EVENT, btn, [=](std::string) {
if (callbackOper) { callbackOper(row, 0, title); } if (callbackOper) { callbackOper(row, 0, title); }
}); });
@@ -239,7 +239,7 @@ PvPagination::PvPagination(PARAM* p, int parent, int x, int y, int n)
PvApp::bind(p, PvEvent::BUTTON_EVENT, btn, [=](string) { this->activePage(i, true); }); PvApp::bind(p, PvEvent::BUTTON_EVENT, btn, [=](string) { this->activePage(i, true); });
} }
btnNext = PvApp::button(p, pvid, 32, 0, 30, 30, ">", STYLE_NORMAL); btnNext = PvApp::button(p, pvid, 32, 0, 30, 30, ">", STYLE_NORMAL);
labelInfo = PvApp::label(p, pvid, 2*32, 0, 80, 30, " 共0页", qss::label(14, "rgb(27, 220, 224)")); labelInfo = PvApp::label(p, pvid, 2*32, 0, 80, 30, " 共0页", QSS::label(14, "rgb(27, 220, 224)"));
pvSetEnabled(p, btnPrev, 0); pvSetEnabled(p, btnPrev, 0);
pvSetEnabled(p, btnNext, 0); pvSetEnabled(p, btnNext, 0);

View File

@@ -4,9 +4,9 @@
static int CreatePanel(PARAM* p, int parentId, int x, int y, int w, int h, std::string title) static int CreatePanel(PARAM* p, int parentId, int x, int y, int w, int h, std::string title)
{ {
int id = PvApp::label(p, parentId, x, y, w, h, "", qss::LABEL_BKG_2); int id = PvApp::label(p, parentId, x, y, w, h, "", QSS::LABEL_BKG_2);
PvApp::label(p, id, 10, 10, w, 20, title, qss::STYLE_TITLE_ICON); PvApp::label(p, id, 10, 10, w, 20, title, QSS::STYLE_TITLE_ICON);
PvApp::label(p, id, 20, 30, w, 2, "", qss::QSS_UNDERLINE); PvApp::label(p, id, 20, 30, w, 2, "", QSS::QSS_UNDERLINE);
return id; return id;
} }

View File

@@ -19,9 +19,9 @@ void TestPage(PARAM* p)
static int CreatePanel(PARAM* p, int parent, int x, int y, int w, int h, std::string title) static int CreatePanel(PARAM* p, int parent, int x, int y, int w, int h, std::string title)
{ {
int panelId = PvApp::label(p, parent, x, y, w, h, "", qss::LABEL_BKG_1); int panelId = PvApp::label(p, parent, x, y, w, h, "", QSS::LABEL_BKG_1);
int titleId = PvApp::label(p, panelId, 10, 8, w, 22, title, qss::STYLE_TITLE_ICON); int titleId = PvApp::label(p, panelId, 10, 8, w, 22, title, QSS::STYLE_TITLE_ICON);
PvApp::label(p, panelId, 20, 28, w, 2, "", qss::QSS_UNDERLINE); PvApp::label(p, panelId, 20, 28, w, 2, "", QSS::QSS_UNDERLINE);
return panelId; return panelId;
} }
@@ -35,7 +35,7 @@ static int CreatePanel1(PARAM* p, int parent, int x, int y, int w, int h, std::s
static int CreateCard1(PARAM* p, int parentId, int x, int y, int w, int h, std::string title, std::string val) static int CreateCard1(PARAM* p, int parentId, int x, int y, int w, int h, std::string title, std::string val)
{ {
int id = PvApp::label(p, parentId, x, y, w, h, "", qss::LABEL_BKG_1); int id = PvApp::label(p, parentId, x, y, w, h, "", QSS::LABEL_BKG_1);
int idTitle = PvApp::label(p, id, 0, h*0.5, w, h*0.5, title, "background:transparent; font: bold 28px;"); int idTitle = PvApp::label(p, id, 0, h*0.5, w, h*0.5, title, "background:transparent; font: bold 28px;");
int idVal = PvApp::label(p, id, 0, 0, w, h*0.5, val, "background:transparent; font: bold 28px; color:rgb(77,215,240);"); int idVal = PvApp::label(p, id, 0, 0, w, h*0.5, val, "background:transparent; font: bold 28px; color:rgb(77,215,240);");
pvSetAlignment(p, idTitle, AlignCenter); pvSetAlignment(p, idTitle, AlignCenter);
@@ -45,7 +45,7 @@ static int CreateCard1(PARAM* p, int parentId, int x, int y, int w, int h, std::
static int CreateCard2(PARAM* p, int parent, int x, int y, int w, int h, std::string title, std::string val) static int CreateCard2(PARAM* p, int parent, int x, int y, int w, int h, std::string title, std::string val)
{ {
int id = PvApp::label(p, parent, x, y, w, h, "", qss::LABEL_BKG_1); int id = PvApp::label(p, parent, x, y, w, h, "", QSS::LABEL_BKG_1);
int idTitle = PvApp::label(p, id, 0, 0, w, h*0.5, title); int idTitle = PvApp::label(p, id, 0, 0, w, h*0.5, title);
int idVal = PvApp::label(p, id, 0, h*0.5, w, h*0.5, val, "background:transparent; font: bold 16px; color:rgb(77,215,240);"); int idVal = PvApp::label(p, id, 0, h*0.5, w, h*0.5, val, "background:transparent; font: bold 16px; color:rgb(77,215,240);");
@@ -59,15 +59,15 @@ static int CreateBox(PARAM* p, int parent, int x, int y, int w, int h, std::stri
int id = PvApp::label(p, parent, x, y, w, h, "", "border-radius:0px; background-color: rgb(7, 45, 66); border: 1px solid rgb(27, 88, 105);"); int id = PvApp::label(p, parent, x, y, w, h, "", "border-radius:0px; background-color: rgb(7, 45, 66); border: 1px solid rgb(27, 88, 105);");
{ {
int len = 10; int len = 10;
std::string qss = "background-color: transparent; border: 1px solid rgb(0, 218, 216);"; std::string QSS = "background-color: transparent; border: 1px solid rgb(0, 218, 216);";
PvApp::label(p, id, 0, 0, len, len, "", qss + "border-width: 2px 0 0 2px"); PvApp::label(p, id, 0, 0, len, len, "", QSS + "border-width: 2px 0 0 2px");
PvApp::label(p, id, w-len, 0, len, len, "", qss + "border-width: 2px 2px 0 0"); PvApp::label(p, id, w-len, 0, len, len, "", QSS + "border-width: 2px 2px 0 0");
PvApp::label(p, id, w-len, h-len, len, len, "", qss + "border-width: 0 2px 2px 0"); PvApp::label(p, id, w-len, h-len, len, len, "", QSS + "border-width: 0 2px 2px 0");
PvApp::label(p, id, 0, h-len, len, len, "", qss + "border-width: 0 0 2px 2px"); PvApp::label(p, id, 0, h-len, len, len, "", QSS + "border-width: 0 0 2px 2px");
} }
// "border:none; background-color: transparent; font: bold 14px; padding-bottom: 0px;" // "border:none; background-color: transparent; font: bold 14px; padding-bottom: 0px;"
int titleId = PvApp::label(p, id, 0, 0, w, h*0.5-2, k); int titleId = PvApp::label(p, id, 0, 0, w, h*0.5-2, k);
int valId = PvApp::label(p, id, 0, h*0.5+2, w, h*0.5-2, val, qss::label(16, "rgb(77, 215, 240)")); int valId = PvApp::label(p, id, 0, h*0.5+2, w, h*0.5-2, val, QSS::label(16, "rgb(77, 215, 240)"));
pvSetAlignment(p, titleId, AlignHCenter | AlignBottom); pvSetAlignment(p, titleId, AlignHCenter | AlignBottom);
pvSetAlignment(p, valId, AlignHCenter | AlignTop); pvSetAlignment(p, valId, AlignHCenter | AlignTop);
return valId; return valId;
@@ -276,7 +276,7 @@ int MaskPageHome::initUI(EPvCode pvcode)
// 中间区域 // 中间区域
{ {
int panel = PvApp::label(p, 0, x = 10+500+10, y, w = 880, h1+h2+h3+20, "", qss::LABEL_BKG_1); int panel = PvApp::label(p, 0, x = 10+500+10, y, w = 880, h1+h2+h3+20, "", QSS::LABEL_BKG_1);
////// 饼图 ////// 饼图
//int left = PvApp::widget(p, panel, 100, 100, 100, 100); //int left = PvApp::widget(p, panel, 100, 100, 100, 100);
@@ -298,7 +298,7 @@ int MaskPageHome::initUI(EPvCode pvcode)
auto popStation = new PopStation(p); auto popStation = new PopStation(p);
popStation->show(0); popStation->show(0);
int btn = PvApp::button(p, panel, 10, 20, 100, 30, "场站一", qss::BTN); int btn = PvApp::button(p, panel, 10, 20, 100, 30, "场站一", QSS::BTN);
PvApp::bind(p, PvEvent::BUTTON_EVENT, btn, [=](std::string) { PvApp::bind(p, PvEvent::BUTTON_EVENT, btn, [=](std::string) {
popStation->setStatus("场站一"); popStation->setStatus("场站一");
pvShow(p, popStation->widget); pvShow(p, popStation->widget);

View File

@@ -8,8 +8,8 @@
static int CreateParamLabel(PARAM* p, int parent, int x, int y, std::string k, std::string v) static int CreateParamLabel(PARAM* p, int parent, int x, int y, std::string k, std::string v)
{ {
PvApp::label(p, parent, x, y, 70, 30, k, qss::LABEL_KEY); PvApp::label(p, parent, x, y, 70, 30, k, QSS::LABEL_KEY);
return PvApp::label(p, parent, x += 70, y, 120, 30, v, qss::LABEL_VAL); return PvApp::label(p, parent, x += 70, y, 120, 30, v, QSS::LABEL_VAL);
} }
class CardDevice : PvObject class CardDevice : PvObject
@@ -22,24 +22,24 @@ public:
CardDevice(PARAM* p, int parent, int x, int y) : PvObject(p) CardDevice(PARAM* p, int parent, int x, int y) : PvObject(p)
{ {
card_ = PvApp::label(p, parent, x, y, 400, 250, "", qss::QSS_CARD_DEVICE); card_ = PvApp::label(p, parent, x, y, 400, 250, "", QSS::QSS_CARD_DEVICE);
PvApp::label(p, card_, 10, 10, 60, 60, "", "border:none; background-color: rgb(39, 158, 145);"); PvApp::label(p, card_, 10, 10, 60, 60, "", "border:none; background-color: rgb(39, 158, 145);");
ui.name = PvApp::label(p, card_, 80, 10, 100, 20, ""); ui.name = PvApp::label(p, card_, 80, 10, 100, 20, "");
ui.code = PvApp::label(p, card_, 80, 30, 100, 20, ""); ui.code = PvApp::label(p, card_, 80, 30, 100, 20, "");
ui.type = PvApp::label(p, card_, 80, 50, 100, 20, "", qss::label(14, "rgb(8, 161, 249)")); ui.type = PvApp::label(p, card_, 80, 50, 100, 20, "", QSS::label(14, "rgb(8, 161, 249)"));
int x1 = 190; int x1 = 190;
ui.online = PvApp::labelAlignCenter(p, card_, x1, 10, 70, 30, "在线", qss::LABEL_VAL); ui.online = PvApp::labelAlignCenter(p, card_, x1, 10, 70, 30, "在线", QSS::LABEL_VAL);
ui.running = PvApp::labelAlignCenter(p, card_, x1 += 70, 10, 70, 30, "空闲", qss::LABEL_VAL); ui.running = PvApp::labelAlignCenter(p, card_, x1 += 70, 10, 70, 30, "空闲", QSS::LABEL_VAL);
ui.err = PvApp::labelAlignCenter(p, card_, x1 += 70, 10, 70, 30, "正常", qss::LABEL_VAL); ui.err = PvApp::labelAlignCenter(p, card_, x1 += 70, 10, 70, 30, "正常", QSS::LABEL_VAL);
PvApp::labelAlignCenter(p, card_, x1 = 190, 40, 70, 30, "在线状态", qss::LABEL_KEY); PvApp::labelAlignCenter(p, card_, x1 = 190, 40, 70, 30, "在线状态", QSS::LABEL_KEY);
PvApp::labelAlignCenter(p, card_, x1 += 70, 40, 70, 30, "工作状态", qss::LABEL_KEY); PvApp::labelAlignCenter(p, card_, x1 += 70, 40, 70, 30, "工作状态", QSS::LABEL_KEY);
PvApp::labelAlignCenter(p, card_, x1 += 70, 40, 70, 30, "故障状态", qss::LABEL_KEY); PvApp::labelAlignCenter(p, card_, x1 += 70, 40, 70, 30, "故障状态", QSS::LABEL_KEY);
PvApp::label(p, card_, 10, 80, 80, 30, "运行分析:", qss::LABEL_KEY); PvApp::label(p, card_, 10, 80, 80, 30, "运行分析:", QSS::LABEL_KEY);
PvApp::button(p, card_, 80, 83, 60, 24, "查看"); PvApp::button(p, card_, 80, 83, 60, 24, "查看");
// 默认创建 10 个参数标签: // 默认创建 10 个参数标签:
@@ -50,8 +50,8 @@ public:
int row = i/2; int row = i/2;
int col = i%2; int col = i%2;
int h = 25; int h = 25;
vecParamLabel[i].first = PvApp::label(p, card_, 10 + 200*col, 115 + h*row, 70, h, "参数"+std::to_string(i) + ":", qss::LABEL_KEY); vecParamLabel[i].first = PvApp::label(p, card_, 10 + 200*col, 115 + h*row, 70, h, "参数"+std::to_string(i) + ":", QSS::LABEL_KEY);
vecParamLabel[i].second = PvApp::label(p, card_, 10 + 200*col + 70, 115 + h*row, 120, h, "---", qss::LABEL_VAL); vecParamLabel[i].second = PvApp::label(p, card_, 10 + 200*col + 70, 115 + h*row, 120, h, "---", QSS::LABEL_VAL);
} }
} }
@@ -166,7 +166,7 @@ int MaskPageRunning::initUI(EPvCode pvcode)
pvHide(p, security.workspace); pvHide(p, security.workspace);
{ {
std::string style = qss::label(20, "white; padding: 0px 0px 0px 10px;", "rgb(8, 54, 91)", "none; border-radius: 5px;"); std::string style = QSS::label(20, "white; padding: 0px 0px 0px 10px;", "rgb(8, 54, 91)", "none; border-radius: 5px;");
for (int i = 0; i<12; ++i) for (int i = 0; i<12; ++i)
{ {
int w = 320, h = 240; int w = 320, h = 240;
@@ -174,20 +174,20 @@ int MaskPageRunning::initUI(EPvCode pvcode)
int cardId = PvApp::label(p, security.workspace, x, y, w, h, "监控点 " + std::to_string(i+1), style); int cardId = PvApp::label(p, security.workspace, x, y, w, h, "监控点 " + std::to_string(i+1), style);
pvSetAlignment(p, cardId, AlignLeft | AlignTop); pvSetAlignment(p, cardId, AlignLeft | AlignTop);
PvApp::label(p, cardId, 10, 40, w-20, h-50, "", qss::label(14, "", "", "8px solid black; border-radius: 0px;")); PvApp::label(p, cardId, 10, 40, w-20, h-50, "", QSS::label(14, "", "", "8px solid black; border-radius: 0px;"));
PvApp::image(p, cardId, (w-77)*0.5, 40+(h-40-77)*0.5, 77, 77, "play1.png"); PvApp::image(p, cardId, (w-77)*0.5, 40+(h-40-77)*0.5, 77, 77, "play1.png");
} }
} }
{ {
int w = 320, h = 50; int w = 320, h = 50;
int pid = PvApp::label(p, security.workspace, 1320, 10, w, 200, "环境温度信息", qss::label(20, "", "", "none;")); int pid = PvApp::label(p, security.workspace, 1320, 10, w, 200, "环境温度信息", QSS::label(20, "", "", "none;"));
pvSetAlignment(p, pid, AlignLeft | AlignTop); pvSetAlignment(p, pid, AlignLeft | AlignTop);
PvApp::label(p, pid, 0, 30, w, 5, "", qss::QSS_UNDERLINE); PvApp::label(p, pid, 0, 30, w, 5, "", QSS::QSS_UNDERLINE);
int x = 0, y = 50; int x = 0, y = 50;
PvApp::label(p, pid, x, y, w, h, "", qss::label(14, "", "rgb(16, 105, 125)", "none; border-radius: 5px 5px 0px 0px;")); PvApp::label(p, pid, x, y, w, h, "", QSS::label(14, "", "rgb(16, 105, 125)", "none; border-radius: 5px 5px 0px 0px;"));
PvApp::label(p, pid, x, y, w, h*2, "", qss::label(14, "", "", "1px solid rgb(12, 255, 251); border-radius: 5px;")); PvApp::label(p, pid, x, y, w, h*2, "", QSS::label(14, "", "", "1px solid rgb(12, 255, 251); border-radius: 5px;"));
{ {
w = w/3; w = w/3;
PvApp::labelCenter(p, pid, x, y, w, h, "点位"); PvApp::labelCenter(p, pid, x, y, w, h, "点位");
@@ -200,13 +200,13 @@ int MaskPageRunning::initUI(EPvCode pvcode)
} }
{ {
int w = 320, h = 50; int w = 320, h = 50;
int pid = PvApp::label(p, security.workspace, 1320, 200, w, 500, "消防信息", qss::label(20, "", "", "none;")); int pid = PvApp::label(p, security.workspace, 1320, 200, w, 500, "消防信息", QSS::label(20, "", "", "none;"));
pvSetAlignment(p, pid, AlignLeft | AlignTop); pvSetAlignment(p, pid, AlignLeft | AlignTop);
PvApp::label(p, pid, 0, 30, w, 5, "", qss::QSS_UNDERLINE); PvApp::label(p, pid, 0, 30, w, 5, "", QSS::QSS_UNDERLINE);
int x = 0, y = 50; int x = 0, y = 50;
PvApp::label(p, pid, x, y, w, h, "", qss::label(14, "", "rgb(16, 105, 125)", "none; border-radius: 5px 5px 0px 0px;")); PvApp::label(p, pid, x, y, w, h, "", QSS::label(14, "", "rgb(16, 105, 125)", "none; border-radius: 5px 5px 0px 0px;"));
PvApp::label(p, pid, x, y, w, h*9, "", qss::label(14, "", "", "1px solid rgb(12, 255, 251); border-radius: 5px;")); PvApp::label(p, pid, x, y, w, h*9, "", QSS::label(14, "", "", "1px solid rgb(12, 255, 251); border-radius: 5px;"));
{ {
w = w/2; w = w/2;
PvApp::labelCenter(p, pid, x, y, w, h, "点位"); PvApp::labelCenter(p, pid, x, y, w, h, "点位");
@@ -246,8 +246,8 @@ void MaskPageRunning::initModule(Module& module, std::string name, int x, int y,
module.name = name; module.name = name;
int deviceNum = activeStation->getDeviceNumByGroup(name); int deviceNum = activeStation->getDeviceNumByGroup(name);
int pid = module.widget = PvApp::label(p, 0, x, y, w, h, "", qss::LABEL_BOX); int pid = module.widget = PvApp::label(p, 0, x, y, w, h, "", QSS::LABEL_BOX);
PvApp::label(p, module.widget, 10, 20, w, 30, module.name, qss::LABEL_TITLE); PvApp::label(p, module.widget, 10, 20, w, 30, module.name, QSS::LABEL_TITLE);
pvSetAlignment(p, module.widget, AlignTop | AlignLeft); pvSetAlignment(p, module.widget, AlignTop | AlignLeft);
module.labelPower = PvApp::lineLabel(p, pid, PvRect(10, 80, 180, 30), 70, "总功率:", "60 W"); module.labelPower = PvApp::lineLabel(p, pid, PvRect(10, 80, 180, 30), 70, "总功率:", "60 W");
module.labelNum = PvApp::lineLabel(p, pid, PvRect(10, 110, 180, 30), 70, "设备数量:", std::to_string(deviceNum).c_str()); module.labelNum = PvApp::lineLabel(p, pid, PvRect(10, 110, 180, 30), 70, "设备数量:", std::to_string(deviceNum).c_str());
@@ -268,13 +268,13 @@ void MaskPageRunning::activeBoxPanel(Module* module)
{ {
if (activeBox) if (activeBox)
{ {
pvSetStyleSheet(p, activeBox->widget, qss::LABEL_BOX.c_str()); pvSetStyleSheet(p, activeBox->widget, QSS::LABEL_BOX.c_str());
pvHide(p, activeBox->workspace); pvHide(p, activeBox->workspace);
} }
activeBox = module; activeBox = module;
if (activeBox) if (activeBox)
{ {
pvSetStyleSheet(p, activeBox->widget, qss::QSS_BOX_ACTIVE.c_str()); pvSetStyleSheet(p, activeBox->widget, QSS::QSS_BOX_ACTIVE.c_str());
pvShow(p, activeBox->workspace); pvShow(p, activeBox->workspace);
} }

View File

@@ -4,9 +4,9 @@
static int CreatePanel(PARAM* p, int parentId, int x, int y, int w, int h, std::string title) static int CreatePanel(PARAM* p, int parentId, int x, int y, int w, int h, std::string title)
{ {
int id = PvApp::label(p, parentId, x, y, w, h, "", qss::LABEL_BKG_2); int id = PvApp::label(p, parentId, x, y, w, h, "", QSS::LABEL_BKG_2);
PvApp::label(p, id, 10, 10, w, 20, title, qss::STYLE_TITLE_ICON); PvApp::label(p, id, 10, 10, w, 20, title, QSS::STYLE_TITLE_ICON);
PvApp::label(p, id, 20, 30, w, 2, "", qss::QSS_UNDERLINE); PvApp::label(p, id, 20, 30, w, 2, "", QSS::QSS_UNDERLINE);
return id; return id;
} }
@@ -52,7 +52,7 @@ static VecStatDef statDef = {
int MaskPageStat::initUI(EPvCode pvcode) int MaskPageStat::initUI(EPvCode pvcode)
{ {
PvApp::label(p, PV_ID_MAIN, 10, 100, 1900, 850, "", qss::LABEL_BKG_1); PvApp::label(p, PV_ID_MAIN, 10, 100, 1900, 850, "", QSS::LABEL_BKG_1);
if (pvcode == EPvCode::MASK_STAT) { pvcode = EPvCode::MASK_STAT_STORAGE; } if (pvcode == EPvCode::MASK_STAT) { pvcode = EPvCode::MASK_STAT_STORAGE; }
std::string curModuleName; std::string curModuleName;
@@ -63,7 +63,7 @@ int MaskPageStat::initUI(EPvCode pvcode)
std::string moduleName = statDef[i].first; std::string moduleName = statDef[i].first;
// 创建按钮 // 创建按钮
bool isActive = (PvApp::getPvCode(moduleName) == pvcode); bool isActive = (PvApp::getPvCode(moduleName) == pvcode);
int pageBtn = PvApp::button(p, PV_ID_MAIN, 10+(i*190), 110, 180, 40, moduleName, isActive ? qss::QSS_BTN_MGR_ACTIVE : qss::QSS_BTN_MGR); int pageBtn = PvApp::button(p, PV_ID_MAIN, 10+(i*190), 110, 180, 40, moduleName, isActive ? QSS::QSS_BTN_MGR_ACTIVE : QSS::QSS_BTN_MGR);
mapSubpage_[pageBtn] = moduleName; mapSubpage_[pageBtn] = moduleName;
if (isActive) if (isActive)
{ {

View File

@@ -79,7 +79,7 @@ MaskPageSysmgr::MaskPageSysmgr(PARAM* p) : PvMask(p)
int MaskPageSysmgr::initUI(EPvCode pvcode) int MaskPageSysmgr::initUI(EPvCode pvcode)
{ {
PvApp::label(p, PV_ID_MAIN, 10, 150, 1900, 790, "", qss::LABEL_BKG_1); PvApp::label(p, PV_ID_MAIN, 10, 150, 1900, 790, "", QSS::LABEL_BKG_1);
if (pvcode == EPvCode::MASK_SYSMGR) { pvcode = EPvCode::MASK_MGR_USER; } if (pvcode == EPvCode::MASK_SYSMGR) { pvcode = EPvCode::MASK_MGR_USER; }
@@ -88,7 +88,7 @@ int MaskPageSysmgr::initUI(EPvCode pvcode)
{ {
std::string& title = vecPageNames[i]; std::string& title = vecPageNames[i];
bool isActive = (PvApp::getPvCode(title) == pvcode); bool isActive = (PvApp::getPvCode(title) == pvcode);
int idPageBtn = PvApp::button(p, PV_ID_MAIN, 10+(i*110), 100, 100, 40, title, isActive ? qss::QSS_BTN_MGR_ACTIVE : qss::QSS_BTN_MGR); int idPageBtn = PvApp::button(p, PV_ID_MAIN, 10+(i*110), 100, 100, 40, title, isActive ? QSS::QSS_BTN_MGR_ACTIVE : QSS::QSS_BTN_MGR);
mapSubpage_[idPageBtn] = title; mapSubpage_[idPageBtn] = title;
} }

View File

@@ -438,12 +438,12 @@ std::string PagePolicy::onPopConfirm(std::shared_ptr<PvPopWidget> pop, Fields& f
// === PageSyslog === // === PageSyslog ===
PageSyslog::PageSyslog(PARAM* p, EPvCode pvcode) : PageTable(p) PageSyslog::PageSyslog(PARAM* p, EPvCode pvcode) : PageTable(p)
{ {
table->addHead(DMSystemLog::LOG_ID, "日志编号", 160, {}); table->addHead(DMLogSystem::LOG_ID, "日志编号", 160, {});
table->addHead(DMSystemLog::TYPE, "日志类型", 160, {}); table->addHead(DMLogSystem::TYPE, "日志类型", 160, {});
table->addHead(DMSystemLog::USER_ACCOUNT, "用户", 160, {}); table->addHead(DMLogSystem::USER_ACCOUNT, "用户", 160, {});
table->addHead(DMSystemLog::CONTENT, "日志详情", 800, {}); table->addHead(DMLogSystem::CONTENT, "日志详情", 800, {});
table->addHead(DMSystemLog::STATUS, "状态", 160, {}); table->addHead(DMLogSystem::STATUS, "状态", 160, {});
table->addHead(DMSystemLog::CREATE_TIME, "记录时间", 200, {}); table->addHead(DMLogSystem::CREATE_TIME, "记录时间", 200, {});
table->addOperate({"查看"}); table->addOperate({"查看"});
} }
void PageSyslog::onQueryTable(PageInfo& pageInfo, std::vector<Fields>& result) void PageSyslog::onQueryTable(PageInfo& pageInfo, std::vector<Fields>& result)
@@ -477,12 +477,12 @@ std::string PageSyslog::onPopConfirm(std::shared_ptr<PvPopWidget> pop, Fields& f
// === PageAlertlog === // === PageAlertlog ===
PageAlertlog::PageAlertlog(PARAM* p, EPvCode pvcode) : PageTable(p) PageAlertlog::PageAlertlog(PARAM* p, EPvCode pvcode) : PageTable(p)
{ {
table->addHead(DMAlertLog::LOG_ID, "日志编号", 160, {}); table->addHead(DMLogAlert::LOG_ID, "日志编号", 160, {});
table->addHead(DMAlertLog::TYPE, "日志类型", 160, {}); table->addHead(DMLogAlert::TYPE, "日志类型", 160, {});
table->addHead(DMAlertLog::DEVICE_ID, "设备ID", 160, {}); table->addHead(DMLogAlert::DEVICE_ID, "设备ID", 160, {});
table->addHead(DMAlertLog::CONTENT, "日志详情", 800, {}); table->addHead(DMLogAlert::CONTENT, "日志详情", 800, {});
table->addHead(DMAlertLog::STATUS, "状态", 160, {}); table->addHead(DMLogAlert::STATUS, "状态", 160, {});
table->addHead(DMAlertLog::CREATE_TIME, "记录时间", 200, {}); table->addHead(DMLogAlert::CREATE_TIME, "记录时间", 200, {});
table->addOperate({"查看"}); table->addOperate({"查看"});
} }
void PageAlertlog::onQueryTable(PageInfo& pageInfo, std::vector<Fields>& result) void PageAlertlog::onQueryTable(PageInfo& pageInfo, std::vector<Fields>& result)

View File

@@ -103,7 +103,7 @@ PanelPolicyPeak::PanelPolicyPeak(PARAM* p, int parent, int ix, int iy, int iw, i
} }
if (row == 0 || col == 0) if (row == 0 || col == 0)
{ {
std::string qssLabel = (row==0) ? qss::label(14, "", "rgb(19, 93, 114)") : ""; std::string qssLabel = (row==0) ? QSS::label(14, "", "rgb(19, 93, 114)") : "";
int label = PvApp::label(p, pvid, x+w*col, y+h*row, w, h, text, qssLabel); int label = PvApp::label(p, pvid, x+w*col, y+h*row, w, h, text, qssLabel);
pvSetAlignment(p, label, AlignCenter); pvSetAlignment(p, label, AlignCenter);
} }
@@ -127,7 +127,7 @@ PanelPolicyPeak::PanelPolicyPeak(PARAM* p, int parent, int ix, int iy, int iw, i
ui.radioPolicy1 = PvApp::radioButton(p, labelPolicy, 80, 0, 80, H, "一充一放"); ui.radioPolicy1 = PvApp::radioButton(p, labelPolicy, 80, 0, 80, H, "一充一放");
ui.radioPolicy2 = PvApp::radioButton(p, labelPolicy, 170, 0, 80, H, "两充两放"); ui.radioPolicy2 = PvApp::radioButton(p, labelPolicy, 170, 0, 80, H, "两充两放");
ui.label1 = PvApp::label(p, pvid, 10, y+=30, 610, 90, "第一次充放电过程", qss::label(14, "", "", "1px solid rgb(49, 130, 141)")); ui.label1 = PvApp::label(p, pvid, 10, y+=30, 610, 90, "第一次充放电过程", QSS::label(14, "", "", "1px solid rgb(49, 130, 141)"));
pvSetAlignment(p, ui.label1, AlignLeft | AlignTop); pvSetAlignment(p, ui.label1, AlignLeft | AlignTop);
{ {
int y0 = 70; int y0 = 70;
@@ -152,7 +152,7 @@ PanelPolicyPeak::PanelPolicyPeak(PARAM* p, int parent, int ix, int iy, int iw, i
ui.arrt1LabelPowerOut = PvApp::textedit(p, labelPowerOut, y0 += 70, 0, 80, H, ""); ui.arrt1LabelPowerOut = PvApp::textedit(p, labelPowerOut, y0 += 70, 0, 80, H, "");
} }
ui.label2 = PvApp::label(p, pvid, 630, y, 610, 90, "第二次充放电过程", qss::label(14, "", "", "1px solid rgb(49, 130, 141)")); ui.label2 = PvApp::label(p, pvid, 630, y, 610, 90, "第二次充放电过程", QSS::label(14, "", "", "1px solid rgb(49, 130, 141)"));
pvSetAlignment(p, ui.label2, AlignLeft | AlignTop); pvSetAlignment(p, ui.label2, AlignLeft | AlignTop);
{ {
int y0 = 70; int y0 = 70;
@@ -394,14 +394,14 @@ PanelPolicyRequire::PanelPolicyRequire(PARAM* p, int parent, int ix, int iy, int
int y = 10; int y = 10;
const int H = 24; const int H = 24;
ui.label1 = PvApp::label(p, pvid, 10, y, 600, 80, "响应削峰指令", qss::label(14, "", "", "1px solid rgb(49, 130, 141)")); ui.label1 = PvApp::label(p, pvid, 10, y, 600, 80, "响应削峰指令", QSS::label(14, "", "", "1px solid rgb(49, 130, 141)"));
pvSetAlignment(p, ui.label1, AlignLeft | AlignTop); pvSetAlignment(p, ui.label1, AlignLeft | AlignTop);
{ {
ui.dischargeSoc = PvApp::lineTextedit(p, ui.label1, PvRect(10, 40, 270, H), 100, "电池SOC阈值", ""); ui.dischargeSoc = PvApp::lineTextedit(p, ui.label1, PvRect(10, 40, 270, H), 100, "电池SOC阈值", "");
ui.dischargePower = PvApp::lineTextedit(p, ui.label1, PvRect(300, 40, 270, H), 70, "放电功率", ""); ui.dischargePower = PvApp::lineTextedit(p, ui.label1, PvRect(300, 40, 270, H), 70, "放电功率", "");
} }
ui.label2 = PvApp::label(p, pvid, 10, y += 90, 600, 90, "响应填谷指令", qss::label(14, "", "", "1px solid rgb(49, 130, 141)")); ui.label2 = PvApp::label(p, pvid, 10, y += 90, 600, 90, "响应填谷指令", QSS::label(14, "", "", "1px solid rgb(49, 130, 141)"));
pvSetAlignment(p, ui.label2, AlignLeft | AlignTop); pvSetAlignment(p, ui.label2, AlignLeft | AlignTop);
{ {
ui.chargeSoc = PvApp::lineTextedit(p, ui.label2, PvRect(10, 40, 270, H), 100, "电池SOC阈值", ""); ui.chargeSoc = PvApp::lineTextedit(p, ui.label2, PvRect(10, 40, 270, H), 100, "电池SOC阈值", "");
@@ -458,7 +458,7 @@ PanelPolicySelf::PanelPolicySelf(PARAM* p, int parent, int ix, int iy, int iw, i
int y = 10; int y = 10;
const int H = 24; const int H = 24;
ui.label1 = PvApp::label(p, pvid, 10, y, 600, 120, "响应削峰指令", qss::label(14, "", "", "1px solid rgb(49, 130, 141)")); ui.label1 = PvApp::label(p, pvid, 10, y, 600, 120, "响应削峰指令", QSS::label(14, "", "", "1px solid rgb(49, 130, 141)"));
pvSetAlignment(p, ui.label1, AlignLeft | AlignTop); pvSetAlignment(p, ui.label1, AlignLeft | AlignTop);
{ {
ui.usedSoc = PvApp::lineTextedit(p, ui.label1, PvRect(10, 40, 270, H), 100, "自用电量比值", ""); ui.usedSoc = PvApp::lineTextedit(p, ui.label1, PvRect(10, 40, 270, H), 100, "自用电量比值", "");

View File

@@ -30,7 +30,7 @@ int pvMain(PARAM* p)
// 管理客户端的连接信息 // 管理客户端的连接信息
PvUser pvuser; PvUser pvuser;
PvApp::setPvUser(p, &pvuser); PvApp::setPvUser(p, &pvuser);
XLOGD() << "Browser client connect: s= " << int(p->s) << ", user=" << int(&pvuser); XLOGD() << "Browser client connect: s= " << int(p->s) << ", user=" << (&pvuser);
// 客户端断开时回调 // 客户端断开时回调
pvSetCleanup(p, onPvThreadCleanup, p); pvSetCleanup(p, onPvThreadCleanup, p);

View File

@@ -15,6 +15,7 @@ module.exports = {
}, },
plugins: ['react', '@typescript-eslint', 'prettier'], // 添加 prettier 插件 plugins: ['react', '@typescript-eslint', 'prettier'], // 添加 prettier 插件
rules: { rules: {
'vue/require-explicit-emits': 'off', // 关闭 emits 声明检查
'vue/v-on-event-hyphenation': 'off', 'vue/v-on-event-hyphenation': 'off',
'prettier/prettier': 'off', 'prettier/prettier': 'off',
'react/react-in-jsx-scope': 'off', // React 17+ 可关闭 JSX 运行时检查 'react/react-in-jsx-scope': 'off', // React 17+ 可关闭 JSX 运行时检查
@@ -24,9 +25,8 @@ module.exports = {
eqeqeq: 0, // 警告使用全等 eqeqeq: 0, // 警告使用全等
quotes: [0, 'single'], // 单引号 quotes: [0, 'single'], // 单引号
singleQuote: 0, singleQuote: 0,
'no-console': ['off'], // 允许所有 console 语句 'no-console': 0, // 不禁用console
// 'no-console': 2, // 不禁用console 'no-debugger': 0, // 警告debugger
'no-debugger': 2, // 警告debugger
'no-var': 2, // 对var禁止 'no-var': 2, // 对var禁止
'no-eval': 0, 'no-eval': 0,
semi: 0, // 强制使用分号 semi: 0, // 强制使用分号

View File

@@ -3,7 +3,7 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve && webpack-dev-server", "serve": "vue-cli-service serve ",
"build": "vue-cli-service build", "build": "vue-cli-service build",
"lint": "vue-cli-service lint", "lint": "vue-cli-service lint",
"show-webpack-version": "webpack --version" "show-webpack-version": "webpack --version"

View File

@@ -6,8 +6,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1.0" /> <meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" /> <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title><%= htmlWebpackPlugin.options.title %></title> <title><%= htmlWebpackPlugin.options.title %></title>
<link rel="stylesheet" href="http://at.alicdn.com/t/c/font_5010233_d9pawp3ats.css" />
<link rel="stylesheet" href="https://at.alicdn.com/t/c/font_5010233_m6gk6vpoxg.css" />
</head> </head>
<body> <body>
<noscript> <noscript>

View File

@@ -1,5 +1,13 @@
<template> <template>
<a-config-provider
:theme="{
token: {
colorPrimary: '#143d7d'
}
}"
>
<router-view /> <router-view />
</a-config-provider>
</template> </template>
<style lang="scss"> <style lang="scss">
@@ -9,7 +17,7 @@
left: 0; left: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
// min-width: 1440px; min-width: 1440px;
// min-height: 900px; min-height: 900px;
} }
</style> </style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,447 @@
<template>
<div class="comtable" >
<div class="table" ref="comtable">
<a-table
bordered
:loading="loading"
:columns="columns"
:scroll="scroll"
:data-source="data.realTableData"
:pagination="false"
:row-class-name="rowClassName"
row-key="id"
:expand-icon="expandIcon"
:row-selection="
data.newTableOpt.select
? {
selectedRowKeys: data.selectedRowKeys,
onChange: onSelectChange
}
: false
"
:expanded-row-keys="data.newTableOpt.expand?data.expandedKeys:null"
size="middle"
:indent-size="30"
@resizeColumn="handleResizeColumn"
>
<template #bodyCell="{ column, record }">
<template v-if="column.scopedSlots">
<slot
v-bind="record"
:name="column.scopedSlots ? column.scopedSlots.customRender : ''"
></slot>
</template>
</template>
<template v-if="data.newTableOpt.expand" #expandedRowRender="{ record }">
<a-table
size="small"
:columns="innerColumns"
:data-source="record.currentLimitList"
:pagination="false"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'type'">
<span>
{{ getType(record.type) }}
</span>
</template>
</template>
</a-table>
</template>
</a-table>
</div>
<div class="pagination" v-if="data.newTableOpt.page">
<a-pagination
v-model:current="data.newPageOption.current"
:total="data.newPageOption.total"
:page-size="data.newPageOption.pageSize"
@change="onChange"
show-size-changer
show-quick-jumper
:show-total="(total) => `${total}`"
:page-size-options="data.pageSizeOptions"
>
</a-pagination>
</div>
</div>
</template>
<script setup>
// <a-select :dropdownMatchSelectWidth="false" size="small" placement="top" />
import {
nextTick,
ref,
toRefs,
reactive,
onMounted,
watch,
defineProps,
defineEmits,
defineExpose,
} from 'vue'
const comtable = ref('')
const props = defineProps({
columns: { type: Array },
tableData: { type: Array },
tableOption: {
type: Object,
default: () => {
return {
loading: false,
page: true,
align: 'center',
expand: false,
select: true,
scroll: { y: 750 }
}
}
},
pageOption: {
type: Object,
default: () => {
return {
current: 1,
pageSize: 10,
total: 1
}
}
},
selectField: {
type: Array,
default: () => {
return []
}
},
rowClick: {
default: () => {}
},
tableH: {
type: Number,
},
})
function handleResizeColumn(w, col) {
col.width = w
}
const mountedScroll = () => {
data.newColumns = [...props.columns]
data.realTableData = [...props.tableData]
// tableScoll()
}
const emit = defineEmits(['handlePagesizeChange'])
const data = reactive({
expandedKeys: [],
newColumns: [],
selectedRowKeys: [],
realColumns: [],
realTableData: [],
selectedRows: [],
defaultTabOpt: {
page: true,
align: 'center',
expand: false,
select: true
},
newPageOption: {},
newTableOpt: {},
pageSizeOptions: ['15', '20', '30', '40', '50', '100'],
mountedScroll
})
const loading = ref(false)
const scroll = ref({})
onMounted(async() => {
data.newColumns = [...props.columns]
data.realTableData = [...props.tableData]
await nextTick()
// console.log(props.tableH, 'props.tableH');
scroll.value = { y: comtable.value.offsetHeight - 56 }
})
watch(
() => props.tableData,
(n, o) => {
if (n) {
data.realTableData = [...n]
}
},
{ deep: true, immediate: true }
)
watch(
() => props.pageOption,
(n, o) => {
data.newPageOption = { ...n }
},
{ deep: true, immediate: true }
)
watch(
() => props.tableOption,
(n, o) => {
data.newTableOpt = { ...data.defaultTabOpt, ...n }
},
{ deep: true, immediate: true }
)
watch(
() => props.tableH,
(n, o) => {
if (n && n !== o) {
const pageH = data.newTableOpt.page ? 42 : 0
scroll.value = { y: n - pageH - 56 }
}
},
// { deep: true, immediate: true }
)
function rowClassName(record, index) {
return 'table-row'
}
function expandIcon(props) {}
function onChange(page, pageSize) {
data.newPageOption.current = page
data.newPageOption.pageSize = pageSize
emit('handlePagesizeChange', data.newPageOption)
}
function onSelectChange(selectedRowKeys, selectedRows) {
data.selectedRowKeys = selectedRowKeys
data.selectedRows = selectedRows
}
defineExpose({ ...toRefs(data), loading, mountedScroll, scroll: data.scroll })
</script>
<style lang="scss" scoped>
@use '../style/color.scss' as *;
.comtable {
border-radius: 8px;
font-size: 14px;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
.table{
flex:1
}
.pagination {
display: flex;
justify-content: flex-end;
margin-top: 10px;
// margin-bottom: 10px;
min-width: 420px;
height: 32px;
}
::v-deep .ant-table-thead > tr > th {
border-inline: 1px solid var(--theme-bg) !important;
background: var(--table-header-bg);
color: var(--theme-text-default);
border-bottom: none;
// &.ant-table-column-has-sorters{
// &::hover{
// background: var(--table-header-bg) !important;
// }
// }
&:last-child {
border-inline-end: 1.5px solid var(--table-header-bg) !important;
}
&:nth-last-child(2) {
border-inline-end: 1.5px solid var(--table-header-bg) !important;
}
}
:deep(.ant-table-container > .ant-table-content > table) {
border-inline-start: 1px solid var(--theme-bg) !important;
}
:deep(.ant-pagination-item-link) {
color: var(--theme-text-default) !important;
height: 100% !important;
display: block !important;
}
}
:deep(
.ant-table-wrapper
.ant-table.ant-table-bordered
> .ant-table-container
> .ant-table-header
> table
) {
border-top: none !important;
}
:deep(.ant-checkbox-checked .ant-checkbox-inner) {
background-color: var(--table-header-bg) !important;
border: none !important;
}
:deep(.ant-checkbox-indeterminate .ant-checkbox-inner:after) {
background-color: var(--table-header-bg) !important;
}
:deep(.ant-pagination) {
.ant-pagination-prev,
.ant-pagination-next {
background: var(--theme-bg) !important;
color: var(--theme-text-default) !important;
}
.ant-select-selector {
border: none !important;
}
.ant-select-arrow {
color: var(--theme-text-default) !important;
}
span.ant-input-affix-wrapper,
.ant-select,
.ant-picker {
width: 110px !important;
border-radius: 8px !important;
}
.ant-select-selection-item {
color: var(--theme-text-default) !important;
}
.ant-select-single:not(.ant-select-customize-input) .ant-select-selector {
background-color: var(--theme-bg) !important;
border-radius: 8px !important;
}
.ant-pagination-total-text,
.ant-pagination-options-quick-jumper {
color: var(--theme-text-default) !important;
margin-inline-end: 9px !important;
}
.ant-pagination-options-quick-jumper input {
background-color: var(--theme-bg) !important;
border: none !important;
color: var(--theme-text-default) !important;
}
.ant-pagination-options .ant-pagination-options-size-changer .ant-select-selector {
color: var(--theme-text-default) !important;
background-color: var(--theme-bg) !important;
}
.ant-select-dropdown {
top: -210px !important;
}
.ant-pagination-item {
&:not(.ant-pagination-item-active):hover{
background: var(--theme-bg) !important;
}
a{
color: var(--theme-text-default) !important;
}
}
.ant-pagination-item-ellipsis {
color: var(--theme-text-default) !important;
}
.ant-pagination-item-active {
border-color: transparent !important;
font-size: 16px;
background: var(--theme-bg1) !important;
a {
color: var(--theme-text2) !important;
}
}
}
:deep(
.ant-table.ant-table-bordered > .ant-table-container > .ant-table-header > table > thead > tr > th
) {
&:nth-last-child(2) {
border-inline-end: 1px solid var(--table-header-bg) !important;
}
}
//表格样式
:deep(.ant-table-tbody) {
color: var(--theme-text-default) !important;
> tr {
&:hover {
> .ant-table-cell {
background-color: var(--table-select) !important;
}
}
td {
border: 1px solid var(--theme-bg-default) !important; /* 第一行单元格边框为红色 */
}
}
// td.ant-table-cell.ant-table-cell-row-hover {
// // background-color: var(--table-select) !important;
// }
}
:deep(.ant-table-body) {
background: var(--theme-bg) !important;
.ant-table-cell {
background: var(--theme-bg) !important;
}
.ant-table-row-selected {
td {
background-color: var(--table-select) !important;
}
}
.ant-table-cell-fix-right.ant-table-cell-fix-right-first,
.ant-table-cell-fix-left {
box-shadow: none !important;
padding: 8px !important;
margin: 0 !important;
}
}
:deep(.ant-table-wrapper .ant-table.ant-table-bordered > .ant-table-container) {
border-inline-start: none !important;
:deep(.ant-progress .ant-progress-text) {
color: var(--theme-text-default) !important;
}
}
:deep(.ant-table-wrapper) {
.ant-table-cell-scrollbar,
.ant-table.ant-table-bordered > .ant-table-container {
box-shadow: none !important;
}
}
:deep(.ant-table-wrapper .ant-table) {
background-color: transparent !important;
}
:deep(
.ant-table-wrapper
.ant-table.ant-table-bordered
> .ant-table-container
> .ant-table-body
> table
> tbody
> tr
> .ant-table-cell-fix-right-first::after
) {
border-inline-end: 1px solid var(--theme-bg) !important;
}
:deep(
.ant-table-wrapper
.ant-table.ant-table-bordered
> .ant-table-container
> .ant-table-header
> table
> thead
> tr
> .ant-table-cell-fix-right-first::after
) {
border-inline-end: 1px solid var(--theme-bg) !important;
}
:deep(.ant-table-wrapper .ant-table-thead th.ant-table-column-has-sorters:hover) {
background: var(--table-select) !important;
}
</style>

View File

@@ -0,0 +1,332 @@
<template>
<div class="search">
<div class="top" v-if="searchOptions.length">
<div class="top-left">
<template v-for="item in searchOptions" :key="item.key">
<!-- 输入框 @change="handleChange"-->
<div class="item">
<span class="label"> {{ item.label }}</span>
<div class="select" v-if="item.type == 'select'">
<a-select
:dropdown-match-select-width="false" v-model:value="formData[item.key]"
allow-clear
:max-tag-count='2'
:placeholder="item.label"
:mode="item.mode ? item.mode : 'combobox'"
>
<a-select-option
:value="option.value"
v-for="option in item.options"
:key="option.value"
>
{{ option.label }}
</a-select-option>
</a-select>
</div>
<!-- 日期选择框 -->
<div class="date-picker" v-if="item.type == 'datePick'">
<a-range-picker
:show-time="{ format: 'HH:mm:ss' }"
value-format="YYYY-MM-DD HH:mm:ss"
v-model:value="formData[item.key]"
/>
</div>
<!-- 输入框 -->
<div class="input" v-if="item.type == 'input'">
<a-input
v-model:value="formData[item.key]"
:placeholder="item.placeholder ? item.placeholder : '请输入' + item.label"
:disabled="item.disabled"
>
</a-input>
</div>
<!-- 插槽 -->
<div class="slot" v-if="item.type == 'slot'">
<slot :name="item.slotName" v-bind="item"></slot>
</div>
</div>
</template>
</div>
<!-- <div :class="[searchOptions.length > 4 ? 'top-right-column' : 'top-right']"> -->
<div class="top-right">
<a-button class="ant-btn-search" @click="changeData">
<template #icon>
<i class="iconfont icon-sousu btn-close" />
</template>
查询
</a-button>
<a-button class="ant-btn-reset" @click="clearData">
<template #icon>
<i class="iconfont icon-chongzhi btn-close" />
</template>
重置
</a-button>
</div>
</div>
<div class="bottom">
<div style="display: flex" v-if="btnOptionList.length">
<div v-for="(item, i) in btnOptionList" :key="i" class="button">
<a-button
:class="'btn-' + item.type"
type="primary"
@click="handelClick(item.type)"
:disabled="item.disabled ? item.disabled : false"
>
{{ item.label }}
</a-button>
</div>
</div>
<slot name="searchboxSlot"></slot>
</div>
</div>
</template>
<script>
export default {
name: 'SearchBox',
components: {},
props: {
titleOption: {
type: Object,
default: () => {
return {
title: '',
info: ''
}
}
},
btnOptionList: {
type: Array,
default: () => {
return []
}
},
searchOptions: {
type: Array,
default: () => {
return []
}
},
fieldList: {
type: Array,
default: () => {
return []
}
}
},
data() {
return {
showTableDropMenu: false,
clearFlag: false,
selectField: [],
formData: {},
options: [],
searchList: []
}
},
watch: {
searchOptions: {
handler(n) {
// this.formData = {}
// n.forEach((item) => {
// // this.$set(this.formData, item.key, item.value)
// })
},
immediate: true,
deep: true
}
},
mounted() {
this.selectField = this.fieldList.map((i) => i.value)
},
methods: {
clear(date) {
if (date.length == 0) {
this.$emit('onSearch', this.formData)
}
},
changeData() {
this.clearFlag = false
this.$emit('onSearch', this.formData)
},
clearData() {
this.clearFlag = true
this.formData = {}
this.$emit('onSearch', this.formData)
},
reseatFormData() {
this.formData = {}
},
handelClick(type) {
this.$emit('operateForm', type)
}
// handleChange() {
// this.$emit("onSearch", this.formData);
// },
// pressEnter() {
// this.$emit("onSearch", this.formData);
// },
}
}
</script>
<style lang="scss" scoped>
// 输入框自动填充后的背景改色
input:-internal-autofill-previewed,
input:-internal-autofill-selected {
-webkit-text-fill-color: var(--theme-text-default);
transition: background-color 500s ease-out 0.5s;
}
:deep(.anticon) {
color: var(--theme-text-default) !important;
}
.search {
display: flex;
flex-direction: column;
justify-content: space-between;
.page-title {
display: flex;
align-items: center;
margin-bottom: 15px;
margin-top: 5px;
color: var(--theme-text-default);
.line {
width: 3px;
height: 20px;
background-color: var(--theme-btn3);
border-radius: 1px;
}
.title-text {
font-size: 18px;
margin-left: 10px;
}
.iconfont {
margin-left: 10px;
font-size: 20px;
color: var(--theme-text3);
}
}
.top {
display: flex;
// align-items: center;
justify-content: space-between;
border-bottom: 1.5px solid var(--theme-bg);
.input {
border-radius: 8px;
display: flex;
width: 145px;
height: 35px;
align-items: center;
}
.date-picker {
width: 360px;
}
.ant-select,
.ant-calendar-picker,
.ant-input {
width: 100%;
}
:deep(.ant-select-selection--single .ant-select-selection__rendered) {
height: 35px !important;
line-height: 35px !important;
}
.label {
width: 80px;
// margin-right: 20px;
color: var(--theme-text-default);
}
.top-right,
.top-right-column {
.ant-btn {
border-radius: 8px !important;
color: var(--theme-text2) !important;
font-weight: 700;
font-size: 14px !important;
display: flex;
justify-content: center;
align-items: center;
border-radius: 2px;
height: 35px !important;
line-height: 35px !important;
padding: 7px 10px !important;
border: none;
&.ant-btn-reset {
background-color: var(--theme-btn3) !important;
}
&.ant-btn-search {
background-color: var(--theme-btn1) !important;
}
.iconfont {
color: #fff;
font-size: 18px;
margin-right: 15px;
cursor: pointer;
margin-right: 8px !important;
}
}
}
.top-right {
// width: 10%;
display: flex;
justify-content: flex-end;
flex-wrap: wrap;
.ant-btn {
&.ant-btn-reset {
margin-left: 10px !important;
}
}
}
.top-right-column {
display: block;
.ant-btn {
&.ant-btn-reset {
margin-top: 10px !important;
}
}
}
.top-left {
// width: 1200px;
display: flex;
flex-wrap: wrap;
align-items: center;
.item {
display: flex;
align-items: center;
margin-bottom: 15px;
margin-right: 20px;
}
}
}
.bottom {
display: flex;
margin-top: 15px;
margin-bottom: 15px;
justify-content: space-between;
align-items: center;
.button{
margin-left: 10px;
}
}
}
</style>

View File

@@ -0,0 +1,176 @@
<template>
<div class="device">
<div class="device-item" v-for="item in 8" :key="item">
<div class="item-header">
<div style="display: flex;width: 50%;">
<div class="icon-bg"></div>
<div class="title">
<span class="number">521245786665412</span>
<span class="name">逆变器1</span>
<span class="number type">逆变器</span>
</div>
</div>
<div class="status">
<div class="status-item">
<span>在线</span>
<span class="text">在线状态</span>
</div>
<div class="status-item">
<span>在线</span>
<span class="text">故障状态</span>
</div>
<div class="status-item">
<span>在线</span>
<span class="text">工作状态</span>
</div>
</div>
</div>
<div class="item-content">
<div v-for="info in chunengInfo" :key="info.key">
<span class="text">{{ info.label }}</span>
<a-button v-if="info.key === 'realTimeData'" type="primary" size="small" @click="openModal">查看</a-button>
<span v-else class="value" >{{ info.value }}</span>
</div>
</div>
</div>
<a-modal v-model:open="modalOpen" @ok="handleOk" width="800px">
<!-- <p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p> -->
</a-modal>
</div>
</template>
<script>
export default {
name: '',
components: {},
props: {},
data() {
return {
modalOpen:false,
chunengInfo: [
{label:'运行模式',key:'operationMode',value:'并网运行'},
{label:'电池储能容量',key:'batteryCapacity',value:'100kWh'},
{ label: '实时电压', key: 'voltage', value: '232.5V' },
{ label: '功率因数', key: 'powerFactor', value: '0.95' },
{ label: '实时电流', key: 'current', value: '0.01A' },
{ label: '额定电压', key: 'ratedVoltage', value: '232.5V' },
{ label: '实时功率', key: 'power', value: '0.01kW' },
{ label: '额定电流', key: 'ratedCurrent', value: '0.01A' },
{ label: '实时数据', key: 'realTimeData', value: '0.01kWh' },
{ label: '额定功率', key: 'ratedPower', value: '0.01kW' },
{ label: '冷却方式', key: 'coolingMethod', value: '风冷' }
],
// guangfuInfo: [
// { label: '实时电压', key: 'voltage', value: '232.5V' },
// { label: '额定电压', key: 'ratedVoltage', value: '232.5V' },
// { label: '实时电流', key: 'current', value: '0.01A' },
// { label: '额定电流', key: 'ratedCurrent', value: '0.01A' },
// { label: '实时功率', key: 'power', value: '0.01kW' },
// { label: '额定功率', key: 'ratedPower', value: '0.01kW' },
// { label: '实时数据', key: 'realTimeData', value: '0.01kWh' }
// ]
}
},
mounted() {},
methods: {
openModal(){
this.modalOpen=true;
},
handleOk(){
this.modalOpen=false;
}
}
}
</script>
<style lang="scss" scoped>
.device {
width: 100%;
height: 100%;
margin-left: 20px;
display: grid;
grid-gap: 20px;
grid-template-columns: 1fr 1fr 1fr;
overflow-y: auto;
.device-item {
// width: 410px;
// height: 340px;
border-radius: 15px;
background: $bg2-color;
padding: 15px;
.item-header {
display: flex;
align-items: center;
height: 70px;
color: #fff;
justify-content: space-between;
.icon-bg {
width: 76px;
height: 72px;
border-radius: 6px;
background: linear-gradient(90deg, #3dfefa 0%, #2a82e4 2.96%, #27a188 100%),
linear-gradient(90deg, #3dfefa 0%, #01dfef 2.96%, #08a5ff 100%);
}
.title {
display: flex;
flex-direction: column;
justify-content: space-around;
margin-left: 15px;
}
.number {
font-size: 12px;
}
.name {
font-size: 14px;
}
.type {
color: #08a5ff;
}
.status {
display: flex;
font-size: 14px;
height: 100%;
width: 50%;
justify-content: space-between;
&-item {
display: flex;
flex-direction: column;
text-align: center;
justify-content: space-evenly;
span:first-child {
font-weight: 700;
}
.text {
color: $text-color;
}
}
}
}
.item-content {
grid-template-columns: 1fr 1fr;
color: #fff;
display: grid;
line-height: 45px;
margin-top: 15px;
padding: 0 10px;
.value {
font-weight: 700;
}
}
.text {
color: $text-color;
}
.video {
margin-top: 10px;
}
}
}
.environment {
width: 200px;
}
</style>

View File

@@ -0,0 +1,129 @@
<template>
<div class="videos">
<div class="video-item" v-for="item in 8" :key="item">
<div class="title">
<span>xxxxz监控点</span>
<img
src="@/assets/images/fillScreen.png"
alt=""
width="23px"
style="margin-left: 10px; cursor: pointer"
/>
</div>
<div class="video">
<video
src="https://media.w3.org/2010/05/sintel/trailer_hd.mp4"
controls="controls"
width="100%"
height="100%"
></video>
</div>
</div>
</div>
<div class="environment">
<div class="item">
<div class="title">环境温湿度信息</div>
<img src="@/assets/images/titleLine.png" alt="" width="100%" />
<div class="content">
<div class="header">
<div>点位</div>
<div>温度</div>
<div>湿度</div>
</div>
<div class="row">
<div>#1</div>
<div>20 </div>
<div>20%</div>
</div>
</div>
</div>
<div class="item" style="margin-top: 40px">
<div class="title">消防信息</div>
<img src="@/assets/images/titleLine.png" alt="" width="100%" />
<div class="content">
<div class="header">
<div>点位</div>
<div>烟感状态</div>
</div>
<div class="row" v-for="value in 6" :key="value">
<div>#{{ value }}</div>
<div>xxx</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: '',
components: {},
props: {},
data() {
return {}
},
mounted() {},
methods: {}
}
</script>
<style lang="scss" scoped>
.videos {
width: calc(100% - 240px);
margin-left: 20px;
display: grid;
grid-gap: 20px;
grid-template-columns: 1fr 1fr 1fr;
overflow-y: auto;
.video-item {
// width: 410px;
// height: 340px;
border-radius: 15px;
background: $bg2-color;
padding: 10px;
.title {
display: flex;
align-items: center;
font-size: 24px;
font-weight: 700;
color: #fff;
}
.video {
margin-top: 10px;
}
}
}
.environment {
width: 220px;
margin-left: 10px;
color: #fff;
.title {
font-size: 24px;
font-weight: 700;
}
.content {
margin-top: 15px;
border-radius: 6px;
border: 1px solid $border-color;
font-size: 18px;
font-weight: 700;
.header {
height: 40px;
background: linear-gradient(90deg, #3dfefa33 0%, #00fffb33 50.17%, #3dfefa33 100%), #3dfefa33;
}
.header,
.row {
display: flex;
div {
flex: 1; /* 每列平分宽度 */
text-align: center; /* 文字水平居中 */
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中(如果需要) */
padding: 10px; /* 可选:添加内边距 */
}
}
}
}
</style>

View File

@@ -1,10 +1,10 @@
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
const routes = [ export const routes = [
{ // {
path: '/', // path: '/',
redirect: '/main' // redirect: '/main'
}, // },
{ {
path: '/login', path: '/login',
name: 'login', name: 'login',
@@ -22,7 +22,66 @@ const routes = [
}, },
{ {
path: 'monitor', path: 'monitor',
component: () => import(/* webpackChunkName: "monitor" */ '@/views/sub/monitor.vue') name: 'monitor',
title: '运行监控',
component: () => import(/* webpackChunkName: "monitor" */ '@/views/monitor.vue')
},
{
path: 'system',
name: 'system',
redirect: '/system/policy',
component: () => import(/* webpackChunkName: "system" */ '@/views/system/index.vue'),
children: [
{
path: 'user',
name: 'user',
title: '用户管理',
component: () => import(/* webpackChunkName: "system" */ '@/views/system/user.vue')
},
{
name: 'role',
path: 'role',
title: '角色管理'
// component: () => import(/* webpackChunkName: "system" */ '@/views/system/role.vue')s
},
{
name: 'permission',
path: 'permission',
title: '权限管理'
},
{
name: 'station',
path: 'station',
title: '场站管理'
},
{
name: 'service',
path: 'service',
title: '服务管理'
},
{
path: 'policy',
name: 'policy',
title: '策略管理',
component: () => import(/* webpackChunkName: "system" */ '@/views/system/policy.vue')
},
{
name: 'device',
path: 'device',
title: '设备管理'
},
{
name: 'log',
path: 'log',
title: '告警日志'
},
{
name: 'syslog',
path: 'syslog',
title: '系统日志'
}
]
} }
] ]
} }

View File

@@ -1,14 +1,49 @@
$border-color:#12FBFF; $border-color: #12fbff;
$btn-confirm: #1C918A;
$btn-del:#D43030;
//级联器样式 //级联器样式
.ant-cascader { .ant-cascader {
.ant-select-selector { .ant-select-selector {
background: none !important; background: none !important;
border: 1px solid $border-color !important; border: 1px solid $border-color !important;
} }
.ant-select-arrow { .ant-select-arrow {
color: $border-color; color: $border-color;
} }
.ant-select-selection-placeholder{
color: #ffffff3b;
} }
}
//按钮样式
// .ant-btn{
// padding: 4px 8px;
// }
.ant-btn-primary{
background: $btn-confirm;
&:hover{
background: $btn-confirm;
opacity: 0.8;
}
&:active{
background: #0f6f6a;
}
}
.btn-del{
background: $btn-del;
&:hover{
background: $btn-del;
opacity: 0.8;
}
&:active{
background: $btn-del;
}
}
//modal样式
.ant-modal .ant-modal-content{
background-image: url('@/assets/images/modalBg.png');
background-size: 100% 100%;
background-color: #ffffff00 !important;
border-radius: 0;
}

View File

@@ -1 +1,5 @@
$border-color:#12FBFF $bg1-color:#052f4d;
$bg2-color:#2169c31f;
$bg3-color:#00d2ff1f;
$text-color:#A6B8DD

View File

@@ -1 +1,34 @@
::-webkit-scrollbar {
width: 5px;
height: 6px;
}
::-webkit-scrollbar-button {
display: none;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-track-piece {
background-color: transparent;
}
::-webkit-scrollbar-thumb {
cursor: pointer;
border-radius: 4px;
background: rgba(144, 147, 153, 0.3);
}
::-webkit-scrollbar-thumb:hover {
background: #989eac;
}
::-webkit-scrollbar-corner {
display: none;
}
::-webkit-resizer {
display: none;
}

View File

@@ -1,11 +1,32 @@
<template> <template>
<div class="main"> <div class="main">
<div class="header"></div> <div class="header"></div>
<div class="page"> <div class="page">
<div class="subMenu" v-if="subMenu.length > 0">
<div
class="subItem"
v-for="subItem in subMenu"
:key="subItem.name"
@click="subMenuClick(subItem)"
:class="subCurrentKey == subItem.path ? 'active' : ''"
>
{{ subItem.title }}
</div>
</div>
<div :class="[subMenu.length > 0 ? 'subcontent' : 'content']">
<router-view /> <router-view />
</div> </div>
</div>
<div class="menu"> <div class="menu">
<div v-for="menu in menuList" :key="menu.name" class="menu-item"> <div
v-for="menu in menuList"
:key="menu.name"
class="menu-item"
@click="menuClick(menu)"
:class="currentKey == menu.path ? 'active' : ''"
>
<i :class="menu.icon"></i> <i :class="menu.icon"></i>
{{ menu.name }} {{ menu.name }}
</div> </div>
@@ -21,29 +42,83 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
currentKey: '',
subCurrentKey: '',
menuList: [ menuList: [
{ {
name: '系统总览', name: '系统总览',
icon: 'icon-xitongguanli' icon: 'icon-xitongguanli'
}, },
{
name: '运行监控',
path: '/monitor'
},
{ {
name: '系统管理', name: '系统管理',
icon: 'icon-xitongguanli', path: '/system',
children: [ children: [
{ {
name: '用户管理', name: '用户管理',
icon: 'icon-yonghuguanli', path: '/user'
children: [ },
{ {
name: '用户列表', name: '角色管理',
icon: 'icon-yonghuguanli', path: '/role'
path: '/user/list' },
{
name: '权限管理',
icon: 'icon-caidanguanli'
},
{
name: '场站管理',
icon: 'icon-caidanguanli'
},
{
name: '服务管理',
icon: 'icon-bumenguanli'
},
{
name: '策略管理',
path: '/policy'
},
{
name: '设备管理',
icon: 'icon-rizhiguanli'
},
{
name: '告警日志',
icon: 'icon-rizhiguanli'
},
{
name: '系统日志',
icon: 'icon-rizhiguanli'
} }
] ]
} }
] ],
subMenu: []
} }
] },
mounted() {
this.initRoute()
},
methods: {
initRoute() {
console.log(this.$route,this.$router)
this.subMenu = this.$route.matched[1].children || []
this.currentKey = '/' + this.$route.fullPath.split('/')[1]
this.subCurrentKey = this.$route.fullPath.split('/')[2]
console.log(this.subCurrentKey)
},
menuClick(menu) {
this.currentKey = menu.path
this.subMenu = menu.children || []
this.$router.push(menu.path)
},
subMenuClick(subMenu) {
this.subCurrentKey = subMenu.path
this.$router.push(subMenu.path)
} }
} }
} }
@@ -58,16 +133,42 @@ export default {
} }
.header { .header {
width: 100%; width: 100%;
height: 80px; height: 70px;
border: 1px solid red; }
.subMenu {
display: flex;
color: #fff;
margin-left: 10px;
padding-bottom: 20px;
.subItem {
width: 96px;
height: 36px;
line-height: 36px;
text-align: center;
background: #132347;
border: 1px solid #2169c3;
border-radius: 8px;
margin-right: 15px;
font-size: 14px;
font-weight: 700;
cursor: pointer;
}
.active {
background: #27a188;
}
} }
.page { .page {
width: calc(100% - 20px); width: calc(100% - 20px);
height: calc(100% - 80px - 15px - 47px - 60px); height: calc(100% - 70px - 65px - 40px);
margin: 40px 10px 20px 10px; margin: 20px 10px;
border-radius: 20px; border-radius: 20px;
// background: #052F4D; }
.content{
height: 100%;
}
.subcontent{
height: calc(100% - 46px);
} }
.menu { .menu {
position: absolute; position: absolute;
@@ -86,6 +187,11 @@ export default {
color: #fff; color: #fff;
font-size: 20px; font-size: 20px;
font-weight: 700; font-weight: 700;
cursor: pointer;
}
.active {
border: 1px solid $border-color;
color: #01b3cd;
} }
} }
</style> </style>

188
web/src/views/monitor.vue Normal file
View File

@@ -0,0 +1,188 @@
<template>
<div class="monitor">
<div class="search">
<div class="left">
<div class="search-item">
<span>场站切换</span>
<a-cascader v-model:value="value" :options="options" placeholder="Please select" />
</div>
</div>
<div class="right">
<div class="search-item">
<span>运行模式</span>
<a-cascader v-model:value="value" :options="options" placeholder="Please select" />
</div>
<div class="search-item">
<span>策略名称</span>
<a-cascader v-model:value="value" :options="options" placeholder="Please select" />
</div>
<div class="search-item">
<a-button type="primary">调控</a-button>
</div>
</div>
</div>
<div class="content">
<div class="stations">
<div class="station-item" v-for="station in stations" :key="station.name" @click="()=>currentKey=station.name" :class="currentKey==station.name?'active':''">
<span class="name">{{ station.name }}</span>
<span class="des">总功率{{ station.power }} W</span>
<span class="des">数量{{ station.num }}</span>
</div>
</div>
<div class="container">
<device v-if="stationType" />
<videos v-else />
</div>
</div>
</div>
</template>
<script>
import device from '@/components/monitor/device.vue'
import videos from '@/components/monitor/videos.vue'
export default {
name: 'MonitorView',
components: {
device,
videos
},
data() {
return {
currentKey:'储能系统1',
stationType: 1,
value: [],
options: [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake'
}
]
}
]
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen'
}
]
}
]
}
],
stations: [
{
name: '储能系统1',
power: 60,
num: 62
},
{
name: '储能系统2',
power: 60,
num: 62
}
// {
// name: "储能系统3",
// power: 60,
// num: 62
// },
// {
// name: "储能系统4",
// }
]
}
}
}
</script>
<style scoped lang="scss">
@import url(@/style/color.scss);
.monitor {
width: 100%;
height: 100%;
padding: 20px;
background: $bg1-color;
border-radius: 15px;
.search {
display: flex;
justify-content: space-between;
.search-item {
span {
margin-right: 20px;
}
color: #fff;
margin-left: 30px;
&:first-child {
margin-left: 0;
}
}
.left,
.right {
display: flex;
}
}
.content {
width: 100%;
height: calc(100% - 32px - 20px);
margin-top: 20px;
display: flex;
justify-content: space-between;
.stations {
min-width: 155px;
max-width: 235px;
width: 13%;
height: 100%;
border-radius: 12px;
background: $bg2-color;
padding: 15px 0;
overflow-y: auto;
.station-item {
width: calc(100% - 30px);
margin: 0 15px 15px 15px;
border-radius: 12px;
display: flex;
flex-direction: column;
color: #fff;
padding: 10px 15px;
cursor: pointer;
.name {
font-size: 20px;
font-weight: 700;
line-height: 50px;
}
.des {
font-size: 14px;
font-weight: 600;
line-height: 40px;
}
}
.active{
background: $bg3-color;
}
}
.container {
width: 87%;
display: flex;
}
}
}
</style>

View File

@@ -1,27 +0,0 @@
<template>
<div class="monitor">
<div class="search">
<div class="left">
<div class="search-item">
<span>场站切换</span>
<a-cascader v-model:value="value" :options="options" placeholder="Please select" />
</div>
</div>
<div class="right"></div>
</div>
</div>
</template>
<script setup>
</script>
<style scoped lang="scss">
.monitor{
padding: 10px;
.search{
display: flex;
justify-content: space-between;
}
}
</style>

View File

@@ -0,0 +1,36 @@
<template>
<div class="system">
<router-view/>
</div>
</template>
<script>
export default {
name: '',
components:{
},
props: {
},
data() {
return {
}
},
mounted() {
},
methods:{
},
}
</script>
<style lang="scss" scoped>
.system{
width: 100%;
height: 100%;
background: $bg1-color;
border-radius: 15px;
}
</style>

View File

@@ -0,0 +1,46 @@
<template>
<div class="policy">
<searchBox :btn-option-list="btnOptionList" @onSearch="onSearch" @operateForm="operateForm"/>
</div>
</template>
<script>
import searchBox from '@/components/SearchBox.vue'
export default {
name: '',
components:{searchBox
},
props: {
},
data() {
return {
btnOptionList:[
{label:'新增',icon:'icon-tianjia',type:'add'},
{label:'删除',icon:'icon-tianjia',type:'del'}
]
}
},
mounted() {
},
methods:{
onSearch(data){
console.log(data)
},
operateForm(type){
console.log(type )
},
}
}
</script>
<style lang="scss" scoped>
.policy{
width: 100%;
height: 100%;
padding: 0 15px;
}
</style>

View File

@@ -0,0 +1,30 @@
<template>
<div >
</div>
</template>
<script>
export default {
name: '',
components:{
},
props: {
},
data() {
return {
}
},
mounted() {
},
methods:{
},
}
</script>
<style lang="scss" scoped>
</style>

View File

@@ -38,8 +38,8 @@ module.exports = defineConfig({
loaderOptions: { loaderOptions: {
scss: { scss: {
additionalData: ` additionalData: `
@use "~@/style/color.scss"; @import "@/style/color.scss";
@use "~@/style/antd.scss"; @import "@/style/antd.scss";
` //在每个 .scss 文件顶部自动添加这行代码,无需手动导入 ` //在每个 .scss 文件顶部自动添加这行代码,无需手动导入
} }
}, },