IPBS_Station/widget.cpp
2024-08-15 11:18:18 +08:00

630 lines
24 KiB
C++

#include <iostream>
#include "widget.h"
#include "./ui_widget.h"
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget){
ui->setupUi(this);
//------------------------------------------------------------------------------------------------
setAttribute(Qt::WA_TranslucentBackground); //设置窗口背景透明
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint); //去掉窗口边框
setAreaMovable(ui->widget_3->rect());
this->setWindowIcon(QIcon(":logo.png"));
QIcon trayIconIcon("./logo.png"); // 使用你的图标路径
trayIcon->setIcon(trayIconIcon);
QObject::connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
QObject::connect(showAction, &QAction::triggered, this, &Widget::show);
trayIconMenu->addAction(showAction);
trayIconMenu->addAction(quitAction);
trayIcon->setContextMenu(trayIconMenu);
trayIcon->show();
SetPage(0);
Btns.emplace_back(ui->HomeBtn);
Btns.emplace_back(ui->SettingsBtn);
Initlogo();
//------------------------------------------------------------------------------------------------
connect(ui->Sub_IP, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &Widget::onCurrentIndexChanged);
connect(ui->HomeBtn, &QPushButton::clicked, this, &Widget::on_pushButton_clicked);
connect(ui->SettingsBtn, &QPushButton::clicked, this, &Widget::on_pushButton_clicked2);
connect(ui->CloseBtn, &QPushButton::clicked, this, [this](){this->close();});
connect(ui->MinBtn, &QPushButton::clicked, this, [this](){this->showMinimized();});
connect(ui->OpenServerBtn, &QPushButton::clicked, this, &Widget::OpenServerClick);
connect(ui->RestBtn, &QPushButton::clicked, this, &Widget::ServerConfigInit);
connect(ui->SetSaveBtn, &QPushButton::clicked, this, &Widget::SetSaveBtn);
connect(ui->LogoBtn, &QPushButton::clicked, this, &Widget::SelectFile);
connect(ui->Web_Port, &QLineEdit::textChanged,
this, &Widget::onTextChanged);
ui->HomeBtn->setFocusPolicy(Qt::NoFocus);
ui->SettingsBtn->setFocusPolicy(Qt::NoFocus);
ui->CloseBtn->setFocusPolicy(Qt::NoFocus);
ui->MinBtn->setFocusPolicy(Qt::NoFocus);
ui->OpenServerBtn->setFocusPolicy(Qt::NoFocus);
//------------------------------------------------------------------------------------------------
SetBtn(0);
// terminateProcessByName("java");
// terminateProcessByName("nginx");
ServerThread.SetThread(&Widget::ServerListening,this);
ServerThread.Start();
foreach (QHostAddress ptr , QNetworkInterface::allAddresses()) {
// 获取ipv4地址
if (ptr.protocol() == QAbstractSocket::IPv4Protocol) {
// 过滤本地回环127.0.0.1
if (!ptr.isLoopback()) {
CCString A = ptr.toString().toStdString();
ui->Sub_IP->addItem(A.c_str());
}
}
}
//------------------------------------------------------------------------------------------------
}
Widget::~Widget(){
delete ui;
}
void Widget::on_pushButton_clicked() {
SetBtn(0);
SetPage(0);
}
void Widget::on_pushButton_clicked2() {
SetBtn(1);
SetPage(1);
}
void Widget::WebThreadRun() {
if (!process->waitForFinished(0)) {
std::cout << "Process failed to finish";
return;
}
while (WebThread.Sign()){
try {
QByteArray output = process->readAllStandardOutput();
QByteArray output2 = nginxprocess->readAllStandardOutput();
if(output != ""){
QMetaObject::invokeMethod(this,[this,output](){
ui->ServerConsele->append(output);
});
}
if(output2 != ""){
QMetaObject::invokeMethod(this,[this,output2](){
QString str = "Nginx:[" + output2 + "]";
ui->ServerConsele->append(str);
});
}
}
catch (const std::exception& e) {
QMetaObject::invokeMethod(this,[this,e](){
QString str = "Nginx:[" + QString(e.what()) + "]";
ui->ServerConsele->append(str);
});
}
Threading::Sleep(1000*1000);
}
}
void Widget::closeEvent(QCloseEvent *event) {
QMessageBox msgBox;
msgBox.setWindowTitle(tr("退出程序"));
msgBox.setText(tr("你确定要退出吗?"));
QPushButton *yesButton = msgBox.addButton(tr("结束程序"), QMessageBox::YesRole);
msgBox.addButton(tr("到托盘"), QMessageBox::NoRole);
msgBox.exec();
if (msgBox.clickedButton() == yesButton)
{
ServerThread.Stop();
WebThread.Stop();
terminateProcessByName("java");
event->accept();
QCoreApplication::quit();
}
else
{
this->hide();
event->ignore(); // 阻止窗口关闭
}
}
bool Widget::WebRunFun() {
if(!ServerFlag){
CCString jre = WebSubPaths + JavaExe;
CCString cmd = jre + " -jar WebSub/SpringWeb.jar";
process->start(cmd.c_str()); // 替换为你想要执行的命令
if (!process->waitForStarted()) {
ui->ServerConsele->append("Failed to start WebJar!");
return false;
}
try{
CCString cmdnginx = NginxExe;
nginxprocess->start(cmdnginx.c_str());
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
if (!nginxprocess->waitForStarted()) {
terminateProcessByName("java");
ui->ServerConsele->append("Failed to start Nginx!");
return false;
}
if(!WebThread.Sign()){
WebThread.SetThread(&Widget::WebThreadRun,this);
WebThread.Start();
}
}
return true;
}
void Widget::SetPage(int i) {
ui->stackedWidget->setCurrentIndex(i);
if(i == 1){
ServerSettings = CText::ReadConfig(ServerSttingsPath.c_str());
if(!ServerSettings.empty()){
ui->CS_IP->setText(ServerSettings["C/S_IP"].c_str());
ui->CS_Port->setText(ServerSettings["C/S_PORT"].c_str());
for (int j = 0; j < ui->Sub_IP->count(); ++j) {
if(ui->Sub_IP->itemText(j) == ServerSettings["Sub_Control_IP"].c_str()){
ui->Sub_IP->setCurrentIndex(j);
}
}
ui->Sub_Port->setText(ServerSettings["Sub_Control_PORT"].c_str());
ui->Sub_Audio_Port->setText(ServerSettings["Sub_Control_Audio_PORT"].c_str());
ui->Web_IP->setText(ui->Sub_IP->currentText());
if(ServerSettings["Sub_Web_PORT"].empty()){
ui->Web_Port->setText("5180");
}
else{
ui->Web_Port->setText(ServerSettings["Sub_Web_PORT"].c_str());
}
if(ServerSettings["Language"] == "English"){
ui->LabguageBox->setCurrentIndex(1);
}
else{
ui->LabguageBox->setCurrentIndex(0);
}
QString str = CCString("['http://" + ui->Sub_IP->currentText().toStdString() + ":" + ui->Web_Port->text().toStdString() + "']").c_str();
ui->Sub_Origins->setText(str);
CCString URL = ui->Sub_IP->currentText().toStdString()+":"+ui->Web_Port->text().toStdString();
ui->HTTPURL->setText(CCString("<a style='color: red; text-decoration: none' href = "+URL+">http://"+URL).c_str());
}
}
}
void Widget::SetBtn(int i) {
for (auto & Btn : Btns) {
Btn->setStyleSheet("QPushButton{\n"
"\tborder-radius:10px;\n"
"\tcolor: rgb(255, 255, 255);\n"
"\tbackground-color: rgba(255, 255, 255, 0);\n"
"}\n"
"\n"
"QPushButton:hover{\n"
"\tborder-radius:10px;\n"
"\tcolor: rgb(255, 255, 255);\n"
"\tbackground-color: rgba(74,89,146, 255);\n"
"}");
}
Btns[i]->setStyleSheet("QPushButton{\n"
"\tborder-radius:10px;\n"
"\tcolor: rgb(255, 255, 255);\n"
"\tbackground-color: rgba(74,89,146, 255);\n"
"}\n"
"\n"
"QPushButton:hover{\n"
"\tborder-radius:10px;\n"
"\tcolor: rgb(255, 255, 255);\n"
"\tbackground-color: rgba(74,89,146, 255);\n"
"}");
}
void Widget::OpenServerClick() {
auto A = CText::ReadConfig(ServerSttingsPath.c_str());
if(A.size() >= 8){
try {
ServerReRun();
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
else{
QMessageBox::information(this,"提示","启动参数错误,请先配置服务器参数!");
}
}
void Widget::OpenFlagBtn(bool F) {
if(!F){
ui->OpenServerBtn->setStyleSheet("QPushButton{\n"
"\tborder-radius:10px;\n"
"\tcolor: rgb(255, 255, 255);\n"
"\tbackground-color: rgba(255,68,138,255);\n"
"}\n"
"\n"
"QPushButton:hover{\n"
"\tborder-radius:10px;\n"
"\tcolor: rgb(255, 255, 255);\n"
"\tbackground-color: rgba(255,100,150, 255);\n"
"}");
ui->OpenServerBtn->setText("打开服务");
}
else{
ui->OpenServerBtn->setStyleSheet("QPushButton{\n"
"\tborder-radius:10px;\n"
"\tcolor: rgb(255, 255, 255);\n"
"\tbackground-color: rgba(255,0,0,255);\n"
"}\n"
"\n"
"QPushButton:hover{\n"
"\tborder-radius:10px;\n"
"\tcolor: rgb(255, 255, 255);\n"
"\tbackground-color: rgba(255,100,150, 255);\n"
"}");
ui->OpenServerBtn->setText("关闭服务");
}
}
void Widget::ServerListening() {
bool F = false,S = false;
while (ServerThread.Sign()){
if(ServerFlag){
try {
F = isJarRunning("java");
S = isJarRunning("nginx");
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
char bus[1024] = {0};
if(ServerFlag){
sprintf(bus,"%d天%d小时%d分%d秒",t,h,f,s);
s++;
if(s >= 60){
f++;
s = 0;
if(f >= 60){
f = 0;
if(h >= 24){
t++;
h = 0;
}
h++;
}
}
}
QMetaObject::invokeMethod(this, [this,F,S,bus](){
SetSuBState(F);
SetWebState(S);
// 获取当前的日期和时间
QDateTime currentDateTime = QDateTime::currentDateTime();
// 将日期时间对象转换为字符串格式
QString currentTime = currentDateTime.toString("yyyy-MM-dd-hh:mm:ss");
ui->NowTime->setText(currentTime);
QString str = bus;
ui->RunTime->setText(str);
if(h == 24){
CCFile::CreateFolder("./Serverlogs");
QString ATime = currentDateTime.toString("yyyy-MM-dd");
CCString p = CCString("./Serverlogs/" + ATime.toStdString() + ".txt");
CCFile File = CCFile(p.c_str(),CC::ios::w,true);
if(File.IsOpen()){
CCString stra = ui->ServerConsele->toPlainText().toStdString();
bool FAS = File.Write((char*)stra.c_str(),stra.length());
if(FAS){
ui->ServerConsele->clear();
}
File.Close();
}
}
});
if(!F && ServerFlag){
QMetaObject::invokeMethod(this, [this](){
OpenFlagBtn(false);
CCString jre = WebSubPaths + JavaExe;
CCString cmd = jre + " -jar WebSub/SpringWeb.jar";
process->start(cmd.c_str()); // 替换为你想要执行的命令
if (!process->waitForStarted()) {
ui->ServerConsele->append("Failed to start WebJar!");
}
});
}
if(!S && ServerFlag){
try{
CCString cmdnginx = NginxExe;
nginxprocess->start(cmdnginx.c_str());
if (!nginxprocess->waitForStarted()) {
ui->ServerConsele->append("Failed to start Nginx!");
}
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
Threading::Sleep(1000 * 1000);
}
}
bool Widget::isJarRunning(const char *jarName) {
#ifdef _WIN32
CCString str = jarName;
str.append(".exe");
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
return false;
}
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnapshot, &pe32)) {
do {
if (_tcsstr(pe32.szExeFile, str.c_str()) != nullptr) {
CloseHandle(hSnapshot);
return true;
}
} while (Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
return false;
#elif __linux__
#endif
}
bool Widget::terminateProcessByName(const char *processName) {
#ifdef _WIN32
CCString str = processName;
str.append(".exe");
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) {
return false;
}
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnapshot, &pe32)) {
do {
if (_tcscmp(pe32.szExeFile, str.c_str()) == 0) {
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID);
if (hProcess != NULL) {
TerminateProcess(hProcess, 0);
CloseHandle(hProcess);
}
}
} while (Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
return true;
#elif __linux__
#endif
}
void Widget::ServerReRun() {
if(ServerFlag){
try {
terminateProcessByName("java");
terminateProcessByName("nginx");
if(ServerFlag){
nginxprocess->close();
process->close();
WebThread.Stop();
ui->ServerConsele->append("Server Close");
OpenFlagBtn(false);
ServerFlag = false;
ui->RunTime->setVisible(false);
t = 0;h = 0;f = 0;s = 0;
}
}
catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
}
else{
bool F = WebRunFun();
if(F){
OpenFlagBtn(true);
ServerFlag = true;
t = 0;h = 0;f = 0;s = 0;
ui->RunTime->setVisible(true);
}
}
}
void Widget::onCurrentIndexChanged(int index) {
ui->Web_IP->setText(ui->Sub_IP->currentText());
CCString URL = ui->Sub_IP->currentText().toStdString()+":"+ui->Web_Port->text().toStdString();
ui->HTTPURL->setText(CCString("<a style='color: red; text-decoration: none' href = "+URL+">http://"+URL).c_str());
QString str = CCString("['http://" + ui->Sub_IP->currentText().toStdString() + ":" + ServerSettings["Sub_Web_PORT"] + "']").c_str();
ui->Sub_Origins->setText(str);
}
void Widget::SetSuBState(bool F) {
if(F){
ui->SubLabel->setStyleSheet("color: rgb(0, 255, 0);");
ui->SubLabel->setText("后端:在线");
}
else{
ui->SubLabel->setStyleSheet("color: rgb(255, 0, 0);");
ui->SubLabel->setText("后端:离线");
}
}
void Widget::SetWebState(bool F) {
if(F){
ui->WebLabel->setStyleSheet("color: rgb(0, 255, 0);");
ui->WebLabel->setText("前端:在线");
}
else{
ui->WebLabel->setStyleSheet("color: rgb(255, 0, 0);");
ui->WebLabel->setText("前端:离线");
}
}
void Widget::onTextChanged(const QString &text) {
ui->Web_IP->setText(ui->Sub_IP->currentText());
CCString URL = ui->Sub_IP->currentText().toStdString()+":"+ui->Web_Port->text().toStdString();
ui->HTTPURL->setText(CCString("<a style='color: red; text-decoration: none' href = "+URL+">http://"+URL).c_str());
QString str = CCString("['http://" + ui->Web_IP->text().toStdString() + ":" + text.toStdString() + "']").c_str();
ui->Sub_Origins->setText(str);
}
void Widget::SetSaveBtn() {
if(ui->CS_IP->text().isEmpty()){
QMessageBox::information(this, "Error", "C/S_IP不能为空");
return;
}
if(ui->CS_Port->text().isEmpty()){
QMessageBox::information(this, "Error", "C/S_Port不能为空");
return;
}
if(ui->Sub_IP->currentText().isEmpty()){
QMessageBox::information(this, "Error", "Sub_IP不能为空");
return;
}
if(ui->Sub_Port->text().isEmpty()){
QMessageBox::information(this, "Error", "Sub_Port不能为空");
return;
}
if(ui->Web_Port->text().isEmpty()){
QMessageBox::information(this, "Error", "Web_Port不能为空");
return;
}
if(ui->Web_IP->text().isEmpty()){
QMessageBox::information(this, "Error", "Web_IP不能为空");
return;
}
if(ui->Sub_Audio_Port->text().isEmpty()){
QMessageBox::information(this, "Error", "Sub_Audio_Port不能为空");
return;
}
if(ui->Sub_Origins->text().isEmpty()){
QMessageBox::information(this, "Error", "Sub_Origins不能为空");
return;
}
FILE *fp = fopen(ServerSttingsPath.c_str(), "w");
if (fp == nullptr) {
QMessageBox::information(this, "Error", "Failed to open ServerSttings file");
return;
}
// 写入配置数据
fprintf(fp, "C/S_IP:%s\n",ui->CS_IP->text().toStdString().c_str());
fprintf(fp, "C/S_PORT:%s\n",ui->CS_Port->text().toStdString().c_str());
fprintf(fp, "Sub_Control_IP:%s\n",ui->Sub_IP->currentText().toStdString().c_str());
fprintf(fp, "Sub_Control_PORT:%s\n",ui->Sub_Port->text().toStdString().c_str());
fprintf(fp, "Sub_Control_Audio_PORT:%s\n",ui->Sub_Audio_Port->text().toStdString().c_str());
fprintf(fp, "Sub_Web_PORT:%s\n",ui->Web_Port->text().toStdString().c_str());
fprintf(fp, "Origins:%s\n",ui->Sub_Origins->text().toStdString().c_str());
fprintf(fp, "#中文简体,English\n");
fprintf(fp, "Language:%s\n",ui->LabguageBox->currentText().toStdString().c_str());
fclose(fp);
fp = fopen(NginxSttingsPath.c_str(), "w");
if (fp == nullptr) {
QMessageBox::information(this, "Error", "Failed to open NginxSttings file");
return;
}
// 写入配置数据
fprintf(fp, "worker_processes 1;\n"
"events {\n"
" worker_connections 1024;\n"
"}\n"
"http {\n"
" include mime.types;\n"
" default_type application/octet-stream;\n"
" sendfile on;\n"
" keepalive_timeout 65;\n"
" server {\n"
" listen %s;\n"
" server_name %s;\n"
" location / {\n"
" # root html;\n"
" index index.html index.htm;\n"
" try_files $uri $uri/ /index.html;\n"
" # try_files $uri $uri/ @router;\n"
" }\n"
" location /api/ {\n"
" #rewrite ^.+api/?(.*)$ /$1 break; \n"
" rewrite ^/api/(.*)$ /$1 break; \n"
" proxy_pass http://%s:%s/;\n"
" proxy_redirect off;\n"
" proxy_set_header Host $host;\n"
" proxy_set_header X-Real-IP $remote_addr;\n"
" proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n"
" }\n"
" error_page 500 502 503 504 /50x.html;\n"
" location = /50x.html {\n"
" root html;\n"
" }\n"
" }\n"
"}",ui->Web_Port->text().toStdString().c_str(),ui->Web_IP->text().toStdString().c_str(),
ui->Sub_IP->currentText().toStdString().c_str(),ui->Sub_Port->text().toStdString().c_str());
fclose(fp);
QMessageBox::information(this, "Success", "Write OK!");
}
void Widget::ServerConfigInit() {
QString IP = ui->Sub_IP->currentText();
ui->CS_IP->setText(IP);
ui->CS_Port->setText("5418");
ui->Web_IP->setText(IP);
ui->Sub_Port->setText("5417");
ui->Web_Port->setText("5180");
ui->Sub_Audio_Port->setText("52018");
QString str = CCString("['http://" + ui->Web_IP->text().toStdString() + ":" + ui->Web_Port->text().toStdString() + "']").c_str();
ui->Sub_Origins->setText(str);
ui->LabguageBox->setCurrentIndex(0);
}
void Widget::Initlogo() {
QPixmap pixmap("./html/assets/logo-CuXNbvLG.png"); // 替换为你的图片路径
ui->logoIMG->setPixmap(pixmap);
ui->logoIMG->setScaledContents(true); // 图片自动缩放以适应 QLabel 大小
ui->logoIMG->setMaximumSize(111,61); // 设置 QLabel 最小尺寸
ui->logos->setPixmap(pixmap);
ui->logos->setScaledContents(true); // 图片自动缩放以适应 QLabel 大小
ui->logoIMG->setMaximumSize(320,180); // 设置 QLabel 最小尺寸
}
void Widget::SelectFile() {
//定义文件对话框类
QFileDialog *fileDialog = new QFileDialog(this);
//定义文件对话框标题
fileDialog->setWindowTitle(QStringLiteral("选择文件"));
//设置打开的文件路径
fileDialog->setDirectory("./");
//设置文件过滤器,只显示.ui .cpp 文件,多个过滤文件使用空格隔开
fileDialog->setNameFilter(tr("File(*.png*)"));
//设置可以选择多个文件,默认为只能选择一个文件QFileDialog::ExistingFiles
fileDialog->setFileMode(QFileDialog::ExistingFile);
//设置视图模式
fileDialog->setViewMode(QFileDialog::Detail);
//获取选择的文件的路径
QStringList fileNames;
if (fileDialog->exec()) {
fileNames = fileDialog->selectedFiles();
}
CCString fileName = fileNames[0].toStdString();
CCFile file = CCFile(fileName.c_str(), CC::ios::rb, false);
bool F = file.Copy("./html/assets/logo-CuXNbvLG.png");
if(F){
Initlogo();
QMessageBox::information(this, "Success", "Copy OK!");
}
else{
QMessageBox::information(this, "Error", "Failed to copy file");
}
}
bool Widget::isTime235959() {
// 获取当前时间
QTime currentTime = QDateTime::currentDateTime().time();
// 检查时间是否为23:59:59
return currentTime == QTime(16, 01, 59);
}