搭建PVB架构,实现前端的基础布局、菜单、表格、图示等功能

This commit is contained in:
lixiaoyuan
2025-08-20 19:00:22 +08:00
parent 5de7687bcc
commit 7e965b6fb4
142 changed files with 28270 additions and 411 deletions

View File

@@ -0,0 +1,44 @@
#include "MaskPageForecast.h"
#include "pv/PvChart.h"
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);
PvApp::label(p, id, 10, 10, w, 20, title, STYLE_TITLE_ICON);
PvApp::label(p, id, 20, 30, w, 2, "", QSS_UNDERLINE);
return id;
}
MaskPageForecast::MaskPageForecast(PARAM* p) : PvMask(p)
{
}
int MaskPageForecast::initUI(EPvCode pvcode)
{
int x = 10, y = 100, w = 1900, h = 420;
int delta = 40;
{
int panel = CreatePanel(p, 0, x, y, w, h, "储能充放电预测");
chart1_ = std::make_shared<PvChartCurve>(p, panel, 0, delta, w, h-delta);
chart1_->setBackground(p, 8, 54, 91);
chart1_->setLabelYLeft("电量(kWh)", 0, 10, 2);
chart1_->insertItem(0, "充电电量", 120, 10, 80);
chart1_->insertItem(0, "放电电量", 200, 10, 80);
}
{
int panel = CreatePanel(p, 0, x, y+=(h+10), w = 945, h, "光伏发电预测");
chart2_ = std::make_shared<PvChartCurve>(p, panel, 0, delta, w, h-delta);
chart2_->setBackground(p, 8, 54, 91);
chart2_->setLabelYLeft("电量(kWh)", 0, 10, 2);
chart2_->insertItem(0, "发电电量", 120, 10, 80);
}
{
int panel = CreatePanel(p, 0, x+=(w+10), y, w, h, "充电负荷预测");
chart3_ = std::make_shared<PvChartCurve>(p, panel, 0, delta, w, h-delta);
chart3_->setBackground(p, 8, 54, 91);
chart3_->setLabelYLeft("电量(kWh)", 0, 10, 2);
chart3_->insertItem(0, "充电电量", 120, 10, 80);
}
return 0;
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include "pv/PvApp.h"
class PvChartCurve;
class MaskPageForecast : public PvMask
{
public:
MaskPageForecast(PARAM* p);
int initUI(EPvCode pvcode);
std::shared_ptr<PvChartCurve> chart1_;
std::shared_ptr<PvChartCurve> chart2_;
std::shared_ptr<PvChartCurve> chart3_;
};

View File

@@ -0,0 +1,329 @@
#include "MaskPageHome.h"
#include "common/Utils.h"
#include "app/Application.h"
#include "app/Station.h"
#include "pv/PvTable.h"
#include "pv/PvChart.h"
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 titleId = PvApp::label(p, panelId, 10, 8, w, 22, title, STYLE_TITLE_ICON);
PvApp::label(p, panelId, 20, 28, w, 2, "", QSS_UNDERLINE);
return panelId;
}
static int CreatePanel1(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, "", "border: none; background-color: transparent;");
PvApp::image(p, panelId, 0, 13, 500, 17, "bkgBox.png");
PvApp::label(p, panelId, 20, 0, w-20, 30, title, "background-color: transparent; font: bold 18px;");
return panelId;
}
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 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);");
pvSetAlignment(p, idTitle, AlignCenter);
pvSetAlignment(p, idVal, AlignHCenter | AlignBottom);
return id;
}
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 idTitle = PvApp::label(p, id, 0, 0, w, h*0.5, title, "background:transparent; font: bold 16px;");
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);");
pvSetAlignment(p, idTitle, AlignCenter);
pvSetAlignment(p, idVal, AlignCenter);
return id;
}
static int CreateBox(PARAM* p, int parent, int x, int y, int w, int h, std::string k, std::string val="")
{
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;
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, 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, 0, h-len, len, len, "", qss + "border-width: 0 0 2px 2px");
}
int titleId = PvApp::label(p, id, 0, 0, w, h*0.5, k, "border:none; background-color: transparent; font: bold 14px; padding-bottom: 0px;");
int valId = PvApp::label(p, id, 0, h*0.5, w, h*0.5, val, "border:none; background-color: transparent; font: bold 16px; color:rgb(77, 215, 240);");
pvSetAlignment(p, titleId, AlignHCenter | AlignBottom);
pvSetAlignment(p, valId, AlignHCenter | AlignTop);
return valId;
}
static int CreateIconBox(PARAM* p, int parent, int x, int y, std::string k, std::string val, std::string icon)
{
//PvApp::label(p, parent, x, y, 50, 50, "", "background-color: rgb(2, 41, 60); border: 1px solid rgb(61, 254, 250);");
//PvApp::label(p, parent, x+3, y+3, 44, 44, "", "background-color: transparent; border: 2px solid rgb(31, 91, 139);");
PvApp::image(p, parent, x, y, 50, 50, icon.c_str());
PvApp::label(p, parent, x+52, y, 100, 20, k, "background-color: transparent; border: none; font: bold 14px;");
int valId = PvApp::label(p, parent, x+52, y+25, 100, 20, val, "background-color: transparent; border: none; font: bold 14px;");
return valId;
}
class PopStation
{
public:
PARAM* p {};
int widget = PV_ID_NUL;
int width = 1100;
int height = 800;
int labelTitle = PV_ID_NUL;
PopStation(PARAM* p) : p(p)
{
int wMask = 1920, hMask = 960;
widget = PvApp::widget(p, PV_ID_MAIN, 0, 0, wMask, hMask);
PvApp::label(p, widget, 0, 0, 1920, 960, "", "background-color: rgb(1, 32, 54);");
// 站名称Title
labelTitle = PvApp::label(p, widget, 0, 40, wMask, 30, "", "border: none; background-color: transparent; font: bold 20px;");
pvSetAlignment(p, labelTitle, AlignCenter);
{
int pid = PvApp::label(p, widget, (wMask-width)*0.5, (hMask-height)*0.5, width, height, "", "background-color: rgb(2, 58, 87); border: 1px solid rgb(31, 198, 255);");
PvApp::label(p, pid, 0, 0, 80, height, "", "background-color: transparent; border: 3px solid rgb(31, 198, 255); border-width: 3px 0 3px 3px;");
PvApp::label(p, pid, width-80, 0, 80, height, "", "background-color: transparent; border: 3px solid rgb(31, 198, 255); border-width: 3px 3px 3px 0;");
int btnClose = PvApp::button(p, pid, width-40, 5, 30, 30, "", "background-color: white; border: none; border-radius: 15px; color: rgb(2, 59, 87); font: bold 20px;");
PvApp::bind(p, PvEvent::BUTTON_EVENT, btnClose, [=](std::string) {
pvHide(p, widget);
});
int x = 20, y = 40, w = 500, h = 240;
{
int box = CreatePanel1(p, pid, x, y, w, h, "预制舱信息");
int x0 = 50, y0 = 40, w0 = 150, h0 = 60;
CreateBox(p, box, x0 = 60, y0, w0, h0, "电池类型", "磷酸铁锂电池");
CreateBox(p, box, w-x0-w0, y0, w0, h0, "冷却模式", "风冷");
CreateBox(p, box, x0 = 20, y0 += (h0+5), w0, h0, "运行模式", "最优经济化");
CreateBox(p, box, w-x0-w0, y0, w0, h0, "电池额定电压", "300 V");
CreateBox(p, box, x0 = 60, y0 += (h0+5), w0, h0, "PCS额定功率", "100 kW");
CreateBox(p, box, w-x0-w0, y0, w0, h0, "电池储能容量", "100 kWh");
}
{
y += (h+10);
int box = CreatePanel1(p, pid, x, y, w, h, "运行与统计信息");
CreateIconBox(p, box, 40, 40, "舱内温度", "20 ℃", "icon1.png");
CreateIconBox(p, box, 40+160, 40, "舱内湿度", "30 %", "icon2.png");
CreateIconBox(p, box, 40+160*2, 40, "电压", "200 V", "icon3.png");
CreateIconBox(p, box, 40, 90, "电流", "30 A", "icon4.png");
CreateIconBox(p, box, 40+160, 90, "功率", "6 kW", "icon5.png");
CreateIconBox(p, box, 40+160*2, 90, "功率因数", "1.0", "icon5.png");
int x0 = 10, y0 = 160, w0 = 90, h0 = 60;
CreateBox(p, box, x0, y0, w0, h0, "场站运行天数", "365 天");
CreateBox(p, box, x0 += (w0+10), y0, w0, h0, "储能充电电量", "22 kWh");
CreateBox(p, box, x0 += (w0+10), y0, w0, h0, "储能放电电量", "11 kWh");
CreateBox(p, box, x0 += (w0+10), y0, w0, h0, "场站累计收益", "123.12 元");
CreateBox(p, box, x0 += (w0+10), y0, w0, h0, "设备利用率", "10 %");
}
{
y += (h+10);
int box = CreatePanel1(p, pid, x, y, w, h, "环境信息");
CreateIconBox(p, box, 80, 50, "光照强度", "27.1 Lux", "icon1.png");
CreateIconBox(p, box, 80+200*1, 50, "风速", "1.2 m/s", "icon2.png");
CreateIconBox(p, box, 80, 120, "环境温度", "35.7 ℃", "icon1.png");
CreateIconBox(p, box, 80+200*1, 120, "环境湿度", "31.3 %", "icon2.png");
}
{
x = 580; y = 40; h = 240;
int box = CreatePanel1(p, pid, x, y, w, h, "储能充放电量");
PvChartCurve chart(p, box, 0, 40, 500, 200);
chart.setBackground(p, 2, 58, 87);
chart.setLabelYLeft("电量kWh");
chart.insertItem(0, "充电电量", 120, 10, 80);
chart.insertItem(0, "放电电量", 200, 10, 80);
}
{
y += (h+10);
int box = CreatePanel1(p, pid, x, y, w, h, "场站收益");
PvChartCurve chart(p, box, 0, 40, 500, 200);
chart.setBackground(p, 2, 58, 87);
chart.setLabelYLeft("电量(元)");
chart.insertItem(0, "收益", 120, 10, 80);
}
{
y += (h+10);
int box = CreatePanel1(p, pid, x, y, w, h, "设备利用率");
PvChartCurve chart(p, box, 0, 40, 500, 200);
chart.setBackground(p, 2, 58, 87);
chart.setLabelYLeft("利用率(%");
chart.insertItem(0, "利用率", 120, 10, 80);
}
}
}
void setTitle(std::string title)
{
pvSetText(p, labelTitle, title.c_str());
}
void show(int v)
{
v ? pvShow(p, widget) : pvHide(p, widget);
}
};
//background-color: qlineargradient(x1:0, y1:0, x2:1, y2:0,stop:1 rgba(0,255,240,200),stop:0 rgba(0,255,240,0));
int MaskPageHome::initUI(EPvCode pvcode)
{
int x = 10, y = 100, w = 500, h1 = 260, h2=290, h3=290;
// 左侧区域: 上
{
int x0 = 0, y0=40, w0=160, h0=64;
int panel = CreatePanel(p, 0, x, y, w, h1, "运行总览");
ui.labelRunDays = CreateBox(p, panel, x0 = 50, y0, w0, h0, "运行时间");
ui.labelStationNum = CreateBox(p, panel, w-10-w0-x0, y0, w0, h0, "能源站数量");
ui.labelEnergyCapacity = CreateBox(p, panel, x0 = 10, y0+=(h0+10), w0, h0, "储能总容量");
ui.labelIncome = CreateBox(p, panel, w-10-w0-x0, y0, w0, h0, "累计收益");
ui.labelStorageIn = CreateBox(p, panel, x0 = 50, y0 += (h0+10), w0, h0, "累计储能充电量");
ui.labelStorageOut = CreateBox(p, panel, w-10-w0-x0, y0, w0, h0, "累计储能放电量");
}
// 左侧区域: 中
{
int panel = CreatePanel(p, 0, x, y+h1+10, w, h2, "储能设备");
int x1 = 10;
CreateCard2(p, panel, x1, 40, 235, 50, "今日充电电量", "0 kWh");
CreateCard2(p, panel, x1+=245, 40, 235, 50, "今日放电电量", "0 kWh");
auto bar = PvChartBar::create(p, panel, 10, 100, w-20, h2-100);
bar->setLabelYLeft("电量(kWh)");
bar->insertItem("日充电电量");
bar->insertItem("日放电电量");
bar->updateItem(0, {{"08/01", 10}, {"08/02", 20}, {"08/03", 30}, {"08/04", 40}, {"08/05", 50}, {"08/06", 60}, {"08/07", 70}});
bar->updateItem(1, {{"08/01", 1}, {"08/02", 2}, {"08/03", 3}, {"08/04", 4}, {"08/05", 5}, {"08/06", 6}, {"08/07", 7}});
}
// 左侧区域: 下
{
int panel = CreatePanel(p, 0, x, y+h1+h2+20, w, h3, "光伏设备");
int x1 = 10;
CreateCard2(p, panel, x1, 40, 235, 50, "今日发电电量", "0 kWh");
CreateCard2(p, panel, x1 += 245, 40, 235, 50, "今日入网电量", "0 kWh");
auto bar = PvChartBar::create(p, panel, 10, 100, w-20, h3-100);
bar->setLabelYLeft("电量(kWh)");
bar->insertItem("日发电电量");
bar->insertItem("日入网电量");
bar->updateItem(0, {{"08/01", 10}, {"08/02", 20}, {"08/03", 30}, {"08/04", 40}, {"08/05", 50}, {"08/06", 60}, {"08/07", 70}});
}
// 右侧区域:上
{
int panel = CreatePanel(p, 0, x += (880+10+500+10), y, w = 500, h1, "运行分析");
}
// 右侧区域:中
{
int panel = CreatePanel(p, 0, x, y+h1+10, w = 500, h2, "充电设备");
int x1 = 10;
CreateCard2(p, panel, x1, 40, 235, 50, "今日充电电量", "0 kWh");
CreateCard2(p, panel, x1 += 245, 40, 235, 50, "今日充电次数", "0 次");
auto bar = PvChartBar::create(p, panel, 10, 100, w-20, h2-100);
bar->setLabelYLeft("电量(kWh)");
bar->insertItem("日充电电量");
bar->insertItem("日充电次数");
bar->updateItem(0, {{"08/01", 10}, {"08/02", 20}, {"08/03", 30}, {"08/04", 40}, {"08/05", 50}, {"08/06", 60}, {"08/07", 70}});
}
// 右侧区域:下
{
int panel = CreatePanel(p, 0, x, y+h1+h2+20, w = 500, h3, "告警分析");
int x1 = 10;
CreateCard2(p, panel, x1, 40, 153, 50, "今日储能告警", "0 次");
CreateCard2(p, panel, x1 += 163, 40, 153, 50, "今日光伏告警", "0 次");
CreateCard2(p, panel, x1 += 163, 40, 153, 50, "今日充电告警", "0 次");
auto bar = PvChartBar::create(p, panel, 10, 100, w-20, h3-100);
bar->setLabelYLeft("次数");
bar->insertItem("日储能告警");
bar->insertItem("日光伏告警");
bar->insertItem("日充电告警");
bar->updateItem(0, {{"08/01", 10}, {"08/02", 20}, {"08/03", 30}, {"08/04", 40}, {"08/05", 50}, {"08/06", 60}, {"08/07", 70}});
}
// 中间区域
{
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);
//pvSetStyleSheet(p, left, "border: 1px solid gray; border-radius:50px;");
//int id = PvApp::pvid();
//pvDownloadFile(p, "red.png");
//pvQImage(p, id, left, "");
//pvSetGeometry(p, id, 10, 10, 100, 100);
//pvSetImage(p, id, "red.png", 0);
////pvSetStyleSheet(p, id, "border-radius: 50px;");
//int right = PvApp::label(p, panel, 200, 100, 100, 200, "", "border: 1px solid gray;");
//std::string qss = "background: qlineargradient(x1:0, y1 : 0, x2 : 1, y2 : 1, stop : 0 red, stop:1 blue); border-radius: 50px;";
//std::string qss1 = "width: 200px;height: 200px;background: red;transform: rotate(45deg); border-radius: 100px;";
//PvApp::label(p, left, 0, 0, 200, 200, "", qss1);
PvApp::image(p, panel, 0, 20, 880, 800, "map.png");
auto popStation = new PopStation(p);
popStation->show(0);
int btn = PvApp::button(p, panel, 10, 20, 100, 30, "场站一", STYLE_BTN);
PvApp::bind(p, PvEvent::BUTTON_EVENT, btn, [=](std::string) {
popStation->setTitle("场站一");
pvShow(p, popStation->widget);
});
PvApp::image(p, panel, 500, 420, 50, 50, "mapMarker.png");
PvApp::image(p, panel, 420, 500, 50, 50, "mapMarker.png");
PvApp::image(p, panel, 520, 532, 50, 50, "mapMarker.png");
PvApp::image(p, panel, 363, 380, 50, 50, "mapMarker.png");
PvApp::image(p, panel, 545, 564, 50, 50, "mapMarker.png");
}
this->updateUI();
return 0;
}
void MaskPageHome::updateUI()
{
auto& appdata = Application::instance().getAppData();
int stationNum = appdata.mapStation.size(); // 场站数量
double energyCapacity {}; // 储能容量
double incomeTotal {}; // 累计收益
double electStorageIn {}; // 储能充电电量
double electStorageOut {}; // 储能放电电量
for (auto& item : appdata.mapStation)
{
auto& station = item.second;
energyCapacity += station->energyCapacity;
incomeTotal += station->incomeTotal;
}
pvSetText(p, ui.labelRunDays, "100 天");
pvSetText(p, ui.labelRunDays, (Utils::toStr(stationNum) + "").c_str());
pvSetText(p, ui.labelEnergyCapacity, (Utils::toStr(energyCapacity) + " kWh").c_str());
pvSetText(p, ui.labelIncome, (Utils::toStr(incomeTotal) + "").c_str());
pvSetText(p, ui.labelStorageIn, (Utils::toStr(electStorageIn) + " kWh").c_str());
pvSetText(p, ui.labelStorageOut, (Utils::toStr(electStorageOut) + " kWh").c_str());
}

View File

@@ -0,0 +1,37 @@
#pragma once
#include "pv/PvApp.h"
class MaskPageHome : public PvMask
{
public:
// 控件ID的数量需要在创建控件之前确定值和数量
int idCount = 100;
int iconView1;
int welcomeLabel;
int helpLabel;
int buttonRestroom;
public:
MaskPageHome(PARAM* p) : PvMask(p)
{
iconView1 = PvApp::pvid(p);
welcomeLabel = PvApp::pvid(p);
helpLabel = PvApp::pvid(p);
buttonRestroom = PvApp::pvid(p);
}
int initUI(EPvCode pvcode);
void updateUI();
struct {
int labelRunDays;
int labelStationNum;
int labelEnergyCapacity;
int labelIncome;
int labelStorageIn;
int labelStorageOut;
} ui;
};

View File

@@ -0,0 +1,253 @@
#include "MaskPageRunning.h"
#include "app/Application.h"
static std::string QSS_CARD_DEVICE =
"QLabel { background-color:rgb(8, 54, 91); border:0px solid rgb(120, 120, 120); border-radius:5px; font:bold 14px; color:white; }"
"QLabel:hover {border: 2px solid rgb(79, 129, 255); border-radius:2px;}"
"QLabel:disabled { color:rgb(150,150,150);}";
static std::string QSS_PARAM_K = "border:none; background-color: transparent; color: rgb(180,180,180); font: bold 13px;";
static std::string QSS_PARAM_V = "border:none; background-color: transparent; color: white; font: bold 14px;";
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_PARAM_K);
return PvApp::label(p, parent, x += 70, y, 120, 30, v, QSS_PARAM_V);
}
class BoxCard : PvObject
{
public:
static std::shared_ptr<BoxCard> create(PARAM* p, int parent, int x, int y)
{
return std::make_shared<BoxCard>(p, parent, x, y);
}
BoxCard(PARAM* p, int parent, int x, int y) : PvObject(p)
{
card_ = PvApp::label(p, parent, x, y, 400, 250, "", QSS_CARD_DEVICE);
PvApp::label(p, card_, 10, 10, 60, 60, "", "border:none; background-color: rgb(39, 158, 145);");
ui.code = PvApp::label(p, card_, 80, 10, 100, 20, "", "border:none; background-color: transparent;");
ui.name = PvApp::label(p, card_, 80, 30, 100, 20, "", "border:none; background-color: transparent;");
ui.type = PvApp::label(p, card_, 80, 50, 100, 20, "", "border:none; background-color: transparent; color: rgb(8, 161, 249);");
int x1 = 190;
ui.online = PvApp::labelAlignCenter(p, card_, x1, 10, 70, 30, "在线", QSS_PARAM_V);
ui.running = PvApp::labelAlignCenter(p, card_, x1 += 70, 10, 70, 30, "空闲", QSS_PARAM_V);
ui.err = PvApp::labelAlignCenter(p, card_, x1 += 70, 10, 70, 30, "正常", QSS_PARAM_V);
PvApp::labelAlignCenter(p, card_, x1 = 190, 40, 70, 30, "在线状态", QSS_PARAM_K);
PvApp::labelAlignCenter(p, card_, x1 += 70, 40, 70, 30, "工作状态", QSS_PARAM_K);
PvApp::labelAlignCenter(p, card_, x1 += 70, 40, 70, 30, "故障状态", QSS_PARAM_K);
PvApp::label(p, card_, 10, 80, 80, 30, "运行分析:", QSS_PARAM_K);
PvApp::button(p, card_, 80, 83, 60, 24, "查看", "border:none; border-radius: 5px; background-color: rgb(28, 145, 138); color:white; font: bold 14px;");
// 默认创建 10 个参数标签:
int n = 10;
vecParamLabel_.resize(n);
for (int i = 0; i<n; i++)
{
int row = i/2;
int col = i%2;
int h = 25;
vecParamLabel_[i].first = PvApp::label(p, card_, 10 + 200*col, 115 + h*row, 70, h, "参数"+std::to_string(i) + ":", QSS_PARAM_K);
vecParamLabel_[i].second = PvApp::label(p, card_, 10 + 200*col + 70, 115 + h*row, 120, h, "---", QSS_PARAM_V);
}
}
void setCard(std::string type, std::string name, std::string code)
{
if (ui.code != PV_ID_NUL) { pvSetText(p, ui.code, code.c_str()); }
if (ui.name != PV_ID_NUL) { pvSetText(p, ui.name, name.c_str()); }
if (ui.type != PV_ID_NUL) { pvSetText(p, ui.type, type.c_str()); }
}
void setParamkeys(std::vector<std::string> vecKeys)
{
for (int i = 0; i<vecParamLabel_.size(); i++)
{
auto& labelKey = vecParamLabel_[i].first;
auto& labelVal = vecParamLabel_[i].second;
if (i<vecKeys.size())
{
std::string& title = vecKeys[i] + "";
pvSetText(p, labelKey, title.c_str());
pvSetText(p, labelVal, "---");
pvShow(p, labelKey);
pvShow(p, labelVal);
}
else
{
pvHide(p, labelKey);
pvHide(p, labelVal);
}
}
}
void show(int visible)
{
visible ? pvShow(p, card_) : pvHide(p, card_);
}
struct {
int code = PV_ID_NUL;
int name = PV_ID_NUL;
int type = PV_ID_NUL;
int online = PV_ID_NUL;
int running = PV_ID_NUL;
int err = PV_ID_NUL;
} ui;
int card_;
std::vector<std::pair<int, int>> vecParamLabel_;
std::map<std::string, int> mapParam_;
};
MaskPageRunning::MaskPageRunning(PARAM* p) : PvMask(p)
{
}
int MaskPageRunning::initUI(EPvCode pvcode)
{
PvApp::label(p, 0, 10, 100, 1900, 850, "", "background-color: rgb(5, 47, 77); border-radius: 10px;");
PvApp::label(p, 0, 10, 150, 220, 790, "", "background-color: rgb(8, 54, 91); border-radius: 10px;");
int workspace = PvApp::label(p, 0, 240, 150, 1670, 790, "", "background-color: rgba(8, 54, 91, 0); border-radius: 10px;");
std::vector<std::string> vecStationNames;
Application::instance().getAppData().getStationNames(vecStationNames);
PvApp::label(p, 0, 20, 110, 80, 30, "场站切换", "color:white; font: bold 16px;");
PvApp::combox(p, 0, 100, 110, 150, 30, vecStationNames);
if (vecStationNames.size() > 0)
{
station_ = Application::instance().getAppData().getStationByName(vecStationNames[0]);
}
PvApp::label(p, 0, 320, 110, 80, 30, "运行模式", "color:white; font: bold 16px;");
PvApp::combox(p, 0, 400, 110, 200, 30, {"最优经济化运行模式", "最优经济化运行模式", "自定义"});
PvApp::label(p, 0, 670, 110, 80, 30, "策略名称", "color:white; font: bold 16px;");
PvApp::combox(p, 0, 750, 110, 200, 30, {"峰谷套利策略", "需求响应策略", "自发自用上网策略"});
int x = 20, y = 160, w = 200, h = 180;
// 储能设备
{
ui.storage.name = "储能设备";
int pid = ui.storage.box = PvApp::label(p, 0, x, y, w, h, "", QSS_BOX);
PvApp::label(p, pid, 10, 0, w-10, 30, ui.storage.name, QSS_TITLE);
ui.storage.btn = PvApp::button(p, pid, 0, 0, w, h, "", "background-color: transparent;");
ui.storage.workspace = PvApp::widget(p, workspace, 0, 0, 1670, 790);
pvHide(p, ui.storage.workspace);
// 创建信息卡片
{
vecCard_.resize(12);
for (int i=0; i<vecCard_.size(); ++i)
{
vecCard_[i] = BoxCard::create(p, ui.storage.workspace, (i%4)*410, (i/4)*260);
}
}
}
// 光伏设备
{
ui.solar.name = "光伏设备";
int pid = ui.solar.box = PvApp::label(p, 0, x, y += (h+10), w, h, "", QSS_BOX);
PvApp::label(p, pid, 10, 0, w-10, 30, ui.solar.name, QSS_TITLE);
ui.solar.btn = PvApp::button(p, pid, 0, 0, w, h, "", "background-color: transparent;");
ui.solar.workspace = ui.storage.workspace;
pvHide(p, ui.solar.workspace);
}
// 充电设备
{
ui.charge.name = "充电设备";
int pid = ui.charge.box = PvApp::label(p, 0, x, y += (h+10), w, h, "", QSS_BOX);
PvApp::label(p, pid, 10, 0, w-10, 30, ui.solar.name, QSS_TITLE);
ui.charge.btn = PvApp::button(p, pid, 0, 0, w, h, "", "background-color: transparent;");
ui.charge.workspace = ui.storage.workspace;
pvHide(p, ui.charge.workspace);
}
// 环境与安防设备
{
ui.security.name = "环境与安防设备";
int pid = ui.security.box = PvApp::label(p, 0, x, y += (h+10), w, h, "", QSS_BOX);
PvApp::label(p, pid, 10, 0, w-10, 30, ui.security.name, QSS_TITLE);
ui.security.btn = PvApp::button(p, pid, 0, 0, w, h, "", "background-color: transparent;");
ui.security.workspace = PvApp::widget(p, workspace, 0, 0, 1670, 790);
pvHide(p, ui.security.workspace);
}
activeBoxPanel(ui.storage);
{
}
return 0;
}
EPvCode MaskPageRunning::onEventButton(int pvid)
{
if (pvid == ui.storage.btn) { activeBoxPanel(ui.storage); }
else if (pvid == ui.solar.btn) { activeBoxPanel(ui.solar); }
else if (pvid == ui.charge.btn) { activeBoxPanel(ui.charge); }
else if (pvid == ui.security.btn) { activeBoxPanel(ui.security); }
return EPvCode::NUL;
}
std::map<std::string, std::vector<std::string>> mapDeviceTypes =
{
{"储能设备", {"储能预制舱", "储能电池", "储能电池", "储能电池"}},
{"光伏设备", {"光伏板", "光伏板", "光伏板", "光伏板", "光伏板", "光伏板", "光伏板", "光伏板"}},
{"充电设备", {"充电桩", "充电桩", "充电桩", "充电桩", "充电桩", "充电桩", "充电桩", "充电桩", "充电桩", "充电桩"}},
};
std::map<std::string, std::vector<std::string>> mapDeviceParams =
{
{"储能预制舱", {"运行模式", "冷却方式", "实时电压", "额定电压", "实时电流", "额定电流", "实时功率", "额定功率", "功率因数", "电池容量"}},
{"储能电池", {"实时电压", "额定电压", "实时电流", "额定电流", "实时功率", "额定功率", "功率因数", "电池容量"}},
{"逆变器", {"实时电压", "额定电压", "实时电流", "额定电流", "实时功率", "额定功率", "功率因数"}},
{"光伏板", {"实时电压", "额定电压", "实时电流", "额定电流", "实时功率", "额定功率", "功率因数"}},
{"充电桩", {"实时电压", "额定电压", "实时电流", "额定电流", "实时功率", "额定功率", "功率因数"}},
};
void MaskPageRunning::activeBoxPanel(BoxPanel& panel)
{
static int activeBox = PV_ID_NUL;
static int activeWorkspace = PV_ID_NUL;
if (activeBox != PV_ID_NUL) { pvSetStyleSheet(p, activeBox, QSS_BOX.c_str()); }
if (activeBox = panel.box) { pvSetStyleSheet(p, activeBox, QSS_BOX_ACTIVE.c_str()); }
if (activeWorkspace != PV_ID_NUL) { pvHide(p, activeWorkspace); }
if (activeWorkspace = panel.workspace) { pvShow(p, activeWorkspace); }
if (panel.workspace != ui.security.workspace)
{
std::vector<std::string> vecDeviceInfo = mapDeviceTypes[panel.name];
// 读取储能设备信息
for (int i = 0; i<vecCard_.size(); ++i)
{
auto& card = vecCard_[i];
if (i < vecDeviceInfo.size())
{
std::string type = vecDeviceInfo[i];
card->show(1);
card->setCard(type, type+"-"+std::to_string(i), type+"-"+std::to_string(i));
card->setParamkeys(mapDeviceParams[type]);
}
else
{
card->show(0);
}
}
}
}

View File

@@ -0,0 +1,35 @@
#pragma once
#include "pv/PvApp.h"
class BoxCard;
class Station;
class MaskPageRunning : public PvMask
{
public:
struct BoxPanel {
std::string name;
int box;
int btn;
int workspace;
};
MaskPageRunning(PARAM* p);
int initUI(EPvCode pvcode);
virtual EPvCode onEventButton(int pvid);
void activeBoxPanel(BoxPanel& panel);
struct {
BoxPanel storage;
BoxPanel solar;
BoxPanel charge;
BoxPanel security;
} ui;
std::vector<std::shared_ptr<BoxCard>> vecCard_;
std::shared_ptr<Station> station_ = nullptr;
};

View File

@@ -0,0 +1,167 @@
#include "MaskPageStat.h"
#include "pv/PvTable.h"
#include "pv/PvChart.h"
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);
PvApp::label(p, id, 10, 10, w, 20, title, STYLE_TITLE_ICON);
PvApp::label(p, id, 20, 30, w, 2, "", QSS_UNDERLINE);
return id;
}
MaskPageStat::MaskPageStat(PARAM* p) : PvMask(p)
{
}
struct StatChartInfo
{
std::string name;
std::vector<std::string> vecAxis;
std::vector<std::pair<std::string, int>> vecItems;
StatChartInfo(std::string name, std::vector<std::string> axis, std::vector<std::pair<std::string, int>> items) : name(name), vecAxis(axis), vecItems(items) {};
};
using VecChartDef = std::vector<StatChartInfo>;
static VecChartDef chartStorageDef =
{
StatChartInfo {"充放电分析", {"电量(kWh)"}, {{"充电电量", 0}, { "放电电量", 0 }}},
StatChartInfo {"运行状态分析", {"时长(h)", "次数"}, {{"充电时长", 0}, {"放电时长", 0}, {"故障次数", 0}}},
StatChartInfo {"电压/电流分析", {"电压(V)", "电流(A)"}, {{"电压", 0}, {"电流", 0}}},
StatChartInfo {"功率分析", {"功率(kW)"}, {{"功率", 0}}}
};
static VecChartDef chartSolarDef =
{
StatChartInfo {"发电电量分析", {"电量(kWh)"}, {{"发电电量", 0}}},
StatChartInfo {"运行状态分析", {"时长(h)", "次数"}, {{"发电时长", 0}, {"故障次数", 0}}},
StatChartInfo {"电压/电流分析", {"电压(V)", "电流(A)"}, {{"电压", 0}, {"电流", 0}}},
StatChartInfo {"功率分析", {"功率(kW)"}, {{"功率", 0}}}
};
static VecChartDef chartChargeDef =
{
StatChartInfo {"充电分析", {"电量(kWh)"}, {{"充电电量", 0}}},
StatChartInfo {"运行状态分析", {"时长(h)", "次数"}, {{"充电时长", 0}, {"充电次数", 0}, {"故障次数", 0}}},
StatChartInfo {"电压/电流分析", {"电压(V)", "电流(A)"}, {{"电压", 0}, {"电流", 0}}},
StatChartInfo {"功率分析", {"功率(kW)"}, {{"功率", 0}}}
};
using VecStatDef = std::vector<std::pair<std::string, VecChartDef>>;
static VecStatDef statDef = {
{"储能设备运行分析", chartStorageDef},
{"光伏设备运行分析", chartSolarDef},
{"充电设备运行分析", chartChargeDef}
};
int MaskPageStat::initUI(EPvCode pvcode)
{
PvApp::label(p, PV_ID_MAIN, 10, 100, 1900, 850, "", QSS_LABEL_BKG_1);
if (pvcode == EPvCode::MASK_STAT) { pvcode = EPvCode::MASK_STAT_STORAGE; }
std::string curModuleName;
VecChartDef chartDef {};
for (int i = 0; i<statDef.size(); ++i)
{
std::string moduleName = statDef[i].first;
// 创建按钮
bool isActive = (PvApp::getPvCode(moduleName) == pvcode);
int pageBtn = PvApp::button(p, PV_ID_MAIN, 10+(i*190), 110, 180, 40, moduleName, isActive ? QSS_BTN_MGR_ACTIVE : QSS_BTN_MGR);
mapSubpage_[pageBtn] = moduleName;
if (isActive)
{
curModuleName = moduleName;
chartDef = statDef[i].second;
}
}
// 初始化统计图表
if (!chartDef.empty())
{
int x=10, y=160, w=467, h=300, delta = 32;
for (int i = 0; i<chartDef.size(); ++i)
{
auto& chartInfo = chartDef[i];
std::string title = chartInfo.name;
auto& vecAxis = chartInfo.vecAxis;
auto& vecItems = chartInfo.vecItems;
int panel = CreatePanel(p, 0, x+(w+10)*i, y, w, h, title);
if (i == 0)
{
chart1 = std::make_shared<PvChartBar>(p, panel, 0, delta, w, h-delta);
this->initChartBar(chart1, vecAxis, vecItems);
}
else if (i == 1)
{
chart2 = std::make_shared<PvChartBar>(p, panel, 0, delta, w, h-delta);
this->initChartBar(chart2, vecAxis, vecItems);
}
else if (i == 2)
{
chart3 = std::make_shared<PvChartCurve>(p, panel, 0, delta, w, h-delta);
chart3->setBackground(p, 8, 54, 91);
this->initChartCurve(chart3, vecAxis, vecItems);
}
else if (i == 3)
{
chart4 = std::make_shared<PvChartCurve>(p, panel, 0, delta, w, h-delta);
chart4->setBackground(p, 8, 54, 91);
this->initChartCurve(chart4, vecAxis, vecItems);
}
}
}
// 初始化表格
{
PvTable::Options option;
auto table = new PvTable(p, 0, 10, 480, 1900, 12, option);
table->addHead({"日期", "设备ID", "设备名称", "设备类型", "充电次数", "放电次数", "故障次数"});
}
//
{
}
return 0;
}
void MaskPageStat::initChartBar(std::shared_ptr<PvChartBar> chart, std::vector<std::string>& vecAxis, std::vector<std::pair<std::string, int>>& vecItems)
{
if (!chart) { return; }
for (int pos = 0; pos<vecAxis.size(); ++pos)
{
auto text = vecAxis[pos];
if (pos == 0) chart->setLabelYLeft(text);
if (pos == 1) chart->setLabelYRight(text);
}
for (int index = 0; index<vecItems.size(); ++index)
{
chart->insertItem(vecItems[index].first);
}
}
void MaskPageStat::initChartCurve(std::shared_ptr<PvChartCurve> chart, std::vector<std::string>& vecAxis, std::vector<std::pair<std::string, int>>& vecItems)
{
if (!chart) { return; }
for (int pos = 0; pos<vecAxis.size(); ++pos)
{
auto text = vecAxis[pos];
if (pos == 0) chart->setLabelYLeft(text);
if (pos == 1) chart->setLabelYRight(text);
}
for (int index = 0; index<vecItems.size(); ++index)
{
chart->insertItem(vecItems[index].second, vecItems[index].first, 100+80*index, 10, 80);
}
}
EPvCode MaskPageStat::onEventButton(int pvid)
{
std::string title;
auto iter = mapSubpage_.find(pvid);
if (iter != mapSubpage_.end())
{
title = iter->second;
return PvApp::getPvCode(title);
}
return EPvCode::NUL;
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include "pv/PvApp.h"
class PvChartBar;
class PvChartCurve;
class MaskPageStat : public PvMask
{
public:
MaskPageStat(PARAM* p);
int initUI(EPvCode pvcode);
void initChartBar(std::shared_ptr<PvChartBar> chart, std::vector<std::string>& vecAxis, std::vector<std::pair<std::string, int>>& vecItems);
void initChartCurve(std::shared_ptr<PvChartCurve> chart, std::vector<std::string>& vecAxis, std::vector<std::pair<std::string, int>>& vecItems);
EPvCode onEventButton(int pvid) override;
std::map<int, std::string> mapSubpage_;
std::shared_ptr<PvChartBar> chart1;
std::shared_ptr<PvChartBar> chart2;
std::shared_ptr<PvChartCurve> chart3;
std::shared_ptr<PvChartCurve> chart4;
};

View File

@@ -0,0 +1,355 @@
#include "MaskPageSysmgr.h"
#include "pv/PvTable.h"
#include <thread>
#include "database/Dao.h"
#include "pv/PvPopWidget.h"
static void createPvTable(PARAM* p)
{
int nRow = 20, nCol = 10;
int id = PvApp::pvid(p);
pvQTable(p, id, 0, nRow, nCol);
pvSetGeometry(p, id, 10, 200, 1900, 700);
//pvSetWhatsThis()
//pvWhatsThisPrintf()
//pvToolTip()
//pvSetGeometry()
//pvSetMinSize()
//pvSetMaxSize()
//pvMove();
//pvResize();
//pvHide();
//pvShow();
//pvSetStyleSheet()
//pvPrintfStyleSheet();
pvSetPaletteBackgroundColor(p, id, 1, 32, 54);
pvSetPaletteForegroundColor(p, id, 0, 255, 0);
//pvSetFontColor()
//pvSetFont()
//pvSetEnabled()
//pvSetFocus()
//pvCopyToClipboard()
//pvSaveAsBmp()
//pvTablePrintf()
//pvClear();
//pvSetColumnWidth()
//pvSetRowHeight()
//pvSetWordWrap()
//pvSetTablePixmap()
//pvEnsureCellVisible()
pvSetEditable(p, id, 0);
pvTableSetEnabled(p, id, 1, 0, 0);
// 设置垂直vertical方向表头不可 resize
for (int i = 0; i<nRow; ++i) { pvTableSetHeaderResizeEnabled(p, id, 0, 0, i); }
// 设置水平horizontal方向表头不可 resize
for (int i = 0; i<nCol; ++i) { pvTableSetHeaderResizeEnabled(p, id, 1, 0, i); }
pvSetTableText(p, id, -1, -1, "A");
//pvSetTableCheckBox()
//pvSetTableLabel()
pvSetTableButton(p, id, 1, 1, "HelloWorld");
pvSetTableComboBox(p, id, 1, 2, 1, "choice1,#choice2,choice3");
//pvSetNumRows()
//pvSetNumCols()
//pvInsertRows()
//pvInsertColumns()
//pvRemoveRow()
//pvRemoveColumn()
//pvSetTableTextAlignment();
//pvSave()
//pvMysqldump()
//pvCSVcreate()
//pvCSVdump()
//pvCSV()
}
class PageTable : public PvMask
{
public:
PageTable(PARAM* p) : PvMask(p)
{
table = std::make_shared<PvTable>(p, 0, 10, 160, 1900, 20, option);
table->setOperateCallback([=](int row, int col, std::string text) { this->onCallbackOperate(row, col, text); });
};
void setPage(int pageIndex, int pageSize, int count) {}
void updateDataFromDB()
{
std::vector<DataFields> result;
PageInfo pageInfo;
this->queryTable(pageInfo, result);
for (int i = 0; i<table->rows(); ++i)
{
if (i<result.size())
{
auto& fields = result[i];
table->setRowData(i, result[i]);
}
else
{
table->setRowVisible(i, false);
}
}
}
virtual void queryTable(PageInfo& pageInfo, std::vector<DataFields>& result) {}
virtual void onCallbackOperate(int row, int col, std::string text) {};
int pageIndex {0};
PvTable::Options option;
std::shared_ptr<PvTable> table;
std::shared_ptr<PvPopWidget> pop;
};
class PageUser : public PageTable
{
public:
PageUser(PARAM* p, EPvCode pvcode) :PageTable(p)
{
table->addHead(DMUser::USER_ID, "用户编号", 180, {});
table->addHead(DMUser::ACCOUNT, "用户名", 180, {});
table->addHead(DMUser::NAME, "姓名", 180, {});
table->addHead(DMUser::GENDER, "性别", 180, {{"1", ""}, {"0",""}});
table->addHead(DMUser::AGE, "年龄", 180, {});
table->addHead(DMUser::PHONE, "手机号", 180, {});
table->addHead(DMUser::EMAIL, "邮箱", 180, {});
table->addHead("role_id", "角色", 180, {});
table->addHead(DMUser::LOGINTIME, "上次登录时间", 200, {});
table->addOperate({"编辑"});
pop = std::make_shared<PvPopWidget>(p, 700, 500);
pop->show(0);
pop->setCallbackConfirm([=]() {
auto fields = pop->getData();
XLOGD() << fields.toStr();
// 保存数据:
DAO::updateUserById(fields);
});
int x = 50, y = 100, w=350, h=60;
pop->addParamLineEdit(DMUser::USER_ID, "用户编号", x, y, false);
pop->addParamCombox(DMRole::ROLE_ID, "角 色", x+w, y, {"系统管理员", "运营管理员", "运营人员"});
pop->addParamLineEdit(DMUser::ACCOUNT, "用 户 名", x, y+=h);
pop->addParamLineEdit(DMUser::NAME, "姓 名", x+w, y);
pop->addParamLineEdit(DMUser::GENDER, "性 别", x, y+=h);
pop->addParamLineEdit(DMUser::AGE, "年 龄", x+w, y);
pop->addParamLineEdit(DMUser::PHONE, "手 机 号", x, y += h);
pop->addParamLineEdit(DMUser::EMAIL, "邮 箱", x+w, y);
}
void queryTable(PageInfo& pageInfo, std::vector<DataFields>& result)
{
DAO::queryUserList(pageInfo, result);
}
void onCallbackOperate(int row, int col, std::string text)
{
if (text == "编辑")
{
pop->show(1);
pop->setTitle("编辑用户信息");
DataFields fields = table->getRowdata(row);
pop->setData(fields);
}
};
};
class PageRole : public PageTable
{
public:
PageRole(PARAM* p, EPvCode pvcode) : PageTable(p)
{
table->addHead(DMRole::ROLE_ID, "角色编号", 200, {});
table->addHead(DMRole::NAME, "角色名称", 200, {});
table->addHead(DMRole::DESCRIBE, "角色描述", 900, {});
table->addHead(DMRole::IS_OPEN, "是否启用", 200, {{"1", ""}, {"0", ""}});
table->addOperate({"编辑", "设置权限"});
}
void queryTable(PageInfo& pageInfo, std::vector<DataFields>& result)
{
DAO::queryRoleList(pageInfo, result);
}
};
class PagePermission : public PageTable
{
public:
PagePermission(PARAM* p, EPvCode pvcode) : PageTable(p)
{
table->addHead(DMPermission::PERMISSION_ID,"权限编号", 200, {});
table->addHead(DMPermission::NAME, "权限名称", 200, {});
table->addHead(DMPermission::DESCRIBE, "权限描述", 900, {});
table->addHead(DMPermission::IS_OPEN, "是否启用", 200, {{"1", ""}, {"0", ""}});
table->addOperate({"查看"});
}
void queryTable(PageInfo& pageInfo, std::vector<DataFields>& result)
{
DAO::queryPermissionList(pageInfo, result);
}
};
class PageStation : public PageTable
{
public:
PageStation(PARAM* p, EPvCode pvcode) : PageTable(p)
{
table->addHead(DMStation::STATION_ID, "场站编号", 200, {});
table->addHead(DMStation::NAME, "场站名称", 200, {});
table->addHead(DMStation::ADDRESS, "地址", 200, {});
table->addHead(DMStation::LONGITUDE, "经度", 200, {});
table->addHead(DMStation::LATITUDE, "维度", 200, {});
table->addHead(DMStation::TEL, "电话", 200, {});
table->addHead(DMStation::STATUS, "状态", 200, {{"0","未启用"}, {"1", "启用"}});
table->addOperate({"查看", "编辑"});
}
void queryTable(PageInfo& pageInfo, std::vector<DataFields>& result)
{
DAO::queryStationList(pageInfo, result);
}
};
class PageDevice: public PageTable
{
public:
PageDevice(PARAM* p, EPvCode pvcode) : PageTable(p)
{
table->addHead(DMDevice::DEVICE_ID, "设备编号", 120, {});
table->addHead(DMDevice::TYPE, "设备类型", 120, {});
table->addHead(DMDevice::NAME, "设备名称", 180, {});
table->addHead(DMDevice::CODE, "设备编码", 160, {});
table->addHead(DMDevice::MODEL, "设备型号", 160, {});
table->addHead(DMDevice::FACTORY, "厂家", 160, {});
table->addHead(DMDevice::TEL, "厂家电话", 160, {});
table->addHead(DMDevice::ATTRS, "设备参数", 460, {});
table->addHead(DMDevice::IS_OPEN, "是否启用", 120, {{"1", ""}, {"0", ""}});
table->addOperate({"查看", "编辑"});
}
void queryTable(PageInfo& pageInfo, std::vector<DataFields>& result)
{
DAO::queryDeviceList(pageInfo, result);
}
};
class PagePolicy : public PageTable
{
public:
PagePolicy(PARAM* p, EPvCode pvcode) : PageTable(p)
{
table->addHead(DMPolicy::POLICY_ID, "策略编号", 200, {});
table->addHead(DMPolicy::TYPE, "策略类型", 200, {});
table->addHead(DMPolicy::NAME, "策略名称", 200, {});
table->addHead(DMPolicy::DESCRIBE, "策略描述", 400, {});
table->addHead(DMPolicy::VALUE, "策略参数", 400, {});
table->addHead(DMPolicy::IS_OPEN, "是否启用", 200, {{"1", ""}, {"0", ""}});
table->addOperate({"查看", "编辑"});
}
void queryTable(PageInfo& pageInfo, std::vector<DataFields>& result)
{
DAO::queryPolicyList(pageInfo, result);
}
};
class PageSyslog : public PageTable
{
public:
PageSyslog(PARAM* p, EPvCode pvcode) : PageTable(p)
{
table->addHead(DMSystemLog::LOG_ID, "日志编号", 160, {});
table->addHead(DMSystemLog::TYPE, "日志类型", 160, {});
table->addHead(DMSystemLog::USER_ACCOUNT, "用户", 160, {});
table->addHead(DMSystemLog::CONTENT, "日志详情", 800, {});
table->addHead(DMSystemLog::STATUS, "状态", 160, {});
table->addHead(DMSystemLog::CREATE_TIME, "记录时间", 200, {});
table->addOperate({"查看"});
}
void queryTable(PageInfo& pageInfo, std::vector<DataFields>& result)
{
DAO::querySystemLogList(pageInfo, result);
}
};
class PageAlertlog : public PageTable
{
public:
PageAlertlog(PARAM* p, EPvCode pvcode) : PageTable(p)
{
table->addHead(DMAlertLog::LOG_ID, "日志编号", 160, {});
table->addHead(DMAlertLog::TYPE, "日志类型", 160, {});
table->addHead(DMAlertLog::DEVICE_ID, "设备ID", 160, {});
table->addHead(DMAlertLog::CONTENT, "日志详情", 800, {});
table->addHead(DMAlertLog::STATUS, "状态", 160, {});
table->addHead(DMAlertLog::CREATE_TIME, "记录时间", 200, {});
table->addOperate({"查看"});
}
void queryTable(PageInfo& pageInfo, std::vector<DataFields>& result)
{
//DAO::queryAlertLogList(pageInfo, result);
}
};
MaskPageSysmgr::MaskPageSysmgr(PARAM* p) : PvMask(p)
{
}
int MaskPageSysmgr::initUI(EPvCode pvcode)
{
PvApp::label(p, PV_ID_MAIN, 10, 100, 1900, 850, "", QSS_LABEL_BKG_1);
if (pvcode == EPvCode::MASK_SYSMGR) { pvcode = EPvCode::MASK_MGR_USER; }
static std::vector<std::string> vecPageNames = {"用户管理", "角色管理", "权限管理", "场站管理", "设备管理", "策略管理", "系统日志", "告警日志"};
for (int i = 0; i<vecPageNames.size(); ++i)
{
std::string& title = vecPageNames[i];
bool isActive = (PvApp::getPvCode(title) == pvcode);
int idPageBtn = PvApp::button(p, PV_ID_MAIN, 10+(i*110), 110, 100, 40, title, isActive ? QSS_BTN_MGR_ACTIVE : QSS_BTN_MGR);
mapSubpage_[idPageBtn] = title;
}
switch (pvcode)
{
case EPvCode::MASK_MGR_USER: { subpage_ = std::make_shared<PageUser>(p, pvcode); }
break;
case EPvCode::MASK_MGR_ROLE: { subpage_ = std::make_shared<PageRole>(p, pvcode); }
break;
case EPvCode::MASK_MGR_PERMISSION: { subpage_ = std::make_shared<PagePermission>(p, pvcode); }
break;
case EPvCode::MASK_MGR_STATION: { subpage_ = std::make_shared<PageStation>(p, pvcode); }
break;
case EPvCode::MASK_MGR_DEVICE: { subpage_ = std::make_shared<PageDevice>(p, pvcode); }
break;
case EPvCode::MASK_MGR_POLICY: { subpage_ = std::make_shared<PagePolicy>(p, pvcode); }
break;
case EPvCode::MASK_MGR_SYSLOG: { subpage_ = std::make_shared<PageSyslog>(p, pvcode); }
break;
case EPvCode::MASK_MGR_ALERTLOG: { subpage_ = std::make_shared<PageAlertlog>(p, pvcode); }
break;
default:
{
subpage_ = std::make_shared<PageUser>(p, pvcode);
} break;
}
std::thread([=]() {
if (subpage_) { subpage_->updateDataFromDB(); }
}).detach();
return 0;
}
EPvCode MaskPageSysmgr::onEventButton(int pvid)
{
std::string title;
auto iter = mapSubpage_.find(pvid);
if (iter != mapSubpage_.end())
{
title = iter->second;
return PvApp::getPvCode(title);
}
return EPvCode::NUL;
}

View File

@@ -0,0 +1,30 @@
#pragma once
#include "pv/PvApp.h"
class PageTable;
class MaskPageSysmgr : public PvMask
{
public:
MaskPageSysmgr(PARAM* p);
int initUI(EPvCode pvcode);
virtual EPvCode onEventButton(int pvid) override;
struct {
int activePage = PV_ID_NUL;
int pageUser = PV_ID_NUL;
int pageRole = PV_ID_NUL;
int pagePermission = PV_ID_NUL;
int pageStation = PV_ID_NUL;
int pageDevice = PV_ID_NUL;
int pagePolicy = PV_ID_NUL;
int pageSyslog = PV_ID_NUL;
int pageAlertlog = PV_ID_NUL;
} ui;
std::shared_ptr<PageTable> subpage_;
std::map<int, std::string> mapSubpage_;
};