新增缓存数据库存储、转码进度显示
This commit is contained in:
parent
fd38553be1
commit
c097120ca3
|
|
@ -1,4 +1,4 @@
|
|||
QT += core gui widgets
|
||||
QT += core gui widgets sql
|
||||
|
||||
TARGET = Uft30ChangeCode
|
||||
TEMPLATE = app
|
||||
|
|
@ -12,7 +12,11 @@ SOURCES += main.cpp \
|
|||
src/pages/batchconvert/batchconvertpage.cpp \
|
||||
src/pages/functionsearch/functionsearchpage.cpp \
|
||||
src/pages/help/helppage.cpp \
|
||||
src/pages/settings/settingspage.cpp
|
||||
src/pages/settings/settingspage.cpp \
|
||||
src/utils/datacache.cpp \
|
||||
src/utils/uf2configreader.cpp \
|
||||
src/utils/uft3configreader.cpp \
|
||||
src/utils/logmanager.cpp
|
||||
|
||||
HEADERS += src/mainwindow/mainwindow.h \
|
||||
src/pythonrunner/PythonRunner.h \
|
||||
|
|
@ -20,7 +24,11 @@ HEADERS += src/mainwindow/mainwindow.h \
|
|||
src/pages/batchconvert/batchconvertpage.h \
|
||||
src/pages/functionsearch/functionsearchpage.h \
|
||||
src/pages/help/helppage.h \
|
||||
src/pages/settings/settingspage.h
|
||||
src/pages/settings/settingspage.h \
|
||||
src/utils/datacache.h \
|
||||
src/utils/uf2configreader.h \
|
||||
src/utils/uft3configreader.h \
|
||||
src/utils/logmanager.h
|
||||
|
||||
RESOURCES += resources.qrc
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>resources/images/ChangeCode.png</file>
|
||||
<file>resources/images/delect.png</file>
|
||||
<file>resources/images/bianji.png</file>
|
||||
<file>resources/images/zhedie_left.png</file>
|
||||
<file>resources/images/zhedie_right.png</file>
|
||||
<file>resources/images/max.png</file>
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
|
|
@ -3,6 +3,9 @@
|
|||
#include "ElaText.h"
|
||||
#include "ElaTheme.h"
|
||||
#include "ElaToolButton.h"
|
||||
#include "utils/uf2configreader.h"
|
||||
#include "utils/uft3configreader.h"
|
||||
#include "utils/logmanager.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
|
@ -30,39 +33,73 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
initWindow();
|
||||
initContent();
|
||||
|
||||
// 获取应用程序目录
|
||||
LogManager::instance()->initLogFile();
|
||||
LogManager::instance()->logInfo("应用程序启动");
|
||||
|
||||
QString appDir = QCoreApplication::applicationDirPath();
|
||||
|
||||
// 配置 Python 运行器 - 只使用打包好的 exe,路径是 uf2touft3/uf2touft3.exe
|
||||
loadConfigCache();
|
||||
|
||||
m_pythonRunner->setRunMode(PythonRunner::UsePackagedExe);
|
||||
|
||||
// 设置打包好的可执行文件路径和工作目录
|
||||
QString exePath = appDir + "/uf2touft3/uf2touft3.exe";
|
||||
QString workDir = appDir + "/uf2touft3";
|
||||
|
||||
m_pythonRunner->setPackagedExePath(exePath);
|
||||
m_pythonRunner->setWorkingDirectory(workDir);
|
||||
|
||||
// 检查 exe 是否存在
|
||||
QFileInfo exeInfo(exePath);
|
||||
if (!exeInfo.exists() || !exeInfo.isFile()) {
|
||||
m_batchLogEdit->append("⚠️ 警告:未找到 uf2touft3/uf2touft3.exe!");
|
||||
m_batchLogEdit->append(QString(" 期望位置:%1").arg(exePath));
|
||||
LogManager::instance()->logWarning("⚠️ 警告:未找到 uf2touft3/uf2touft3.exe!");
|
||||
LogManager::instance()->log(QString(" 期望位置:%1").arg(exePath));
|
||||
} else {
|
||||
m_batchLogEdit->append("✓ Python 工具准备就绪");
|
||||
LogManager::instance()->log("✓ Python 工具准备就绪");
|
||||
}
|
||||
|
||||
connect(m_pythonRunner, &PythonRunner::finished, this, &MainWindow::onPythonRunnerFinished);
|
||||
connect(m_pythonRunner, &PythonRunner::standardOutput, this, &MainWindow::onPythonRunnerOutput);
|
||||
connect(m_pythonRunner, &PythonRunner::standardError, this, &MainWindow::onPythonRunnerError);
|
||||
connect(m_pythonRunner, &PythonRunner::started, [this]() {
|
||||
m_batchLogEdit->append("转换任务已启动...");
|
||||
connect(m_pythonRunner, &PythonRunner::started, []() {
|
||||
LogManager::instance()->log("转换任务已启动...");
|
||||
});
|
||||
|
||||
// 延迟查找并更新导航按钮(等待窗口完全显示后)
|
||||
QTimer::singleShot(100, this, &MainWindow::updateNavigationButtonIcon);
|
||||
}
|
||||
|
||||
void MainWindow::loadConfigCache()
|
||||
{
|
||||
LogManager::instance()->log("正在加载配置缓存...");
|
||||
|
||||
UF2ConfigReader uf2Reader;
|
||||
bool uf2Loaded = uf2Reader.loadAllUF20Config();
|
||||
|
||||
UFT3ConfigReader uft3Reader;
|
||||
bool uft3Loaded = uft3Reader.loadAllUFT3Config();
|
||||
|
||||
if (uf2Loaded && uft3Loaded) {
|
||||
LogManager::instance()->log("✓ 配置缓存加载完成");
|
||||
} else {
|
||||
LogManager::instance()->logWarning("⚠️ 部分配置加载失败");
|
||||
|
||||
QStringList uf2Failed = uf2Reader.getFailedFiles();
|
||||
QStringList uft3Failed = uft3Reader.getFailedFiles();
|
||||
|
||||
if (!uf2Failed.isEmpty()) {
|
||||
LogManager::instance()->log(" UF20 加载失败:");
|
||||
foreach (const QString& file, uf2Failed) {
|
||||
LogManager::instance()->log(QString(" - %1").arg(file));
|
||||
}
|
||||
}
|
||||
|
||||
if (!uft3Failed.isEmpty()) {
|
||||
LogManager::instance()->log(" UFT3 加载失败:");
|
||||
foreach (const QString& file, uft3Failed) {
|
||||
LogManager::instance()->log(QString(" - %1").arg(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
}
|
||||
|
|
@ -72,6 +109,7 @@ void MainWindow::initWindow()
|
|||
setWindowTitle("UFT30 Change Code");
|
||||
setWindowIcon(QIcon(":/resources/images/ChangeCode.png"));
|
||||
resize(900, 600);
|
||||
setMinimumSize(800, 500);
|
||||
setUserInfoCardVisible(false);
|
||||
|
||||
// 隐藏返回和前进按钮
|
||||
|
|
@ -94,15 +132,10 @@ void MainWindow::initContent()
|
|||
|
||||
QWidget* MainWindow::createBatchConvertPage()
|
||||
{
|
||||
BatchConvertPage *page = new BatchConvertPage;
|
||||
m_batchLogEdit = page->getLogEdit();
|
||||
connect(page, &BatchConvertPage::startConvert, this, &MainWindow::onBatchConvertStart);
|
||||
connect(m_pythonRunner, &PythonRunner::started, [this]() {
|
||||
if (m_batchLogEdit) {
|
||||
m_batchLogEdit->append("转换任务已启动...");
|
||||
}
|
||||
});
|
||||
return page;
|
||||
m_batchConvertPage = new BatchConvertPage;
|
||||
connect(m_batchConvertPage, &BatchConvertPage::startConvert, this, &MainWindow::onBatchConvertStart);
|
||||
connect(m_batchConvertPage, &BatchConvertPage::stopConvert, this, &MainWindow::onBatchConvertStop);
|
||||
return m_batchConvertPage;
|
||||
}
|
||||
|
||||
QWidget* MainWindow::createFunctionSearchPage()
|
||||
|
|
@ -128,7 +161,7 @@ QWidget* MainWindow::createSettingsPage()
|
|||
void MainWindow::onBatchConvertStart()
|
||||
{
|
||||
if (m_pythonRunner->isRunning()) {
|
||||
m_batchLogEdit->append("警告: 上一个任务还在运行中...");
|
||||
LogManager::instance()->logWarning("警告: 上一个任务还在运行中...");
|
||||
QMessageBox::warning(this, "提示", "上一个转换任务正在运行,请等待完成或停止当前任务。");
|
||||
return;
|
||||
}
|
||||
|
|
@ -137,47 +170,124 @@ void MainWindow::onBatchConvertStart()
|
|||
QString exePath = appDir + "/uf2touft3/uf2touft3.exe";
|
||||
|
||||
if (!m_pythonRunner->canRun()) {
|
||||
m_batchLogEdit->append("错误: 找不到 uf2touft3/uf2touft3.exe!");
|
||||
LogManager::instance()->logError("错误: 找不到 uf2touft3/uf2touft3.exe!");
|
||||
QMessageBox::critical(this, "错误",
|
||||
QString("无法启动转换任务!\n\n请确保:\nuf2touft3/uf2touft3.exe 存在,且该目录下包含 config.ini\n\n期望路径:\n%1")
|
||||
.arg(exePath));
|
||||
return;
|
||||
}
|
||||
|
||||
m_batchLogEdit->append("========================================");
|
||||
m_batchLogEdit->append("开始执行 UFT2 到 UFT3 的代码转换...");
|
||||
m_batchLogEdit->append(QString("工具路径: %1").arg(exePath));
|
||||
m_batchLogEdit->append("========================================");
|
||||
if (m_batchConvertPage) {
|
||||
m_totalFunctions = m_batchConvertPage->getFunctionCount();
|
||||
m_functionList = m_batchConvertPage->getFunctionList();
|
||||
m_currentFunctionIndex = 0;
|
||||
} else {
|
||||
m_totalFunctions = 0;
|
||||
m_currentFunctionIndex = 0;
|
||||
m_functionList.clear();
|
||||
}
|
||||
|
||||
LogManager::instance()->log("========================================");
|
||||
LogManager::instance()->log("开始执行 UFT2 到 UFT3 的代码转换...");
|
||||
LogManager::instance()->log(QString("工具路径: %1").arg(exePath));
|
||||
LogManager::instance()->log(QString("待转换函数数量: %1").arg(m_totalFunctions));
|
||||
LogManager::instance()->log("========================================");
|
||||
|
||||
if (!m_pythonRunner->start()) {
|
||||
m_batchLogEdit->append("错误: 无法启动转换进程!");
|
||||
LogManager::instance()->logError("错误: 无法启动转换进程!");
|
||||
} else {
|
||||
if (m_batchConvertPage) {
|
||||
m_batchConvertPage->onConvertStarted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onBatchConvertStop()
|
||||
{
|
||||
if (m_pythonRunner->isRunning()) {
|
||||
LogManager::instance()->log("正在停止转换进程...");
|
||||
m_pythonRunner->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onPythonRunnerFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
m_batchLogEdit->append("========================================");
|
||||
if (m_batchConvertPage) {
|
||||
m_batchConvertPage->onConvertFinished();
|
||||
}
|
||||
|
||||
LogManager::instance()->log("========================================");
|
||||
if (exitStatus == QProcess::NormalExit && exitCode == 0) {
|
||||
m_batchLogEdit->append("✓ 代码转换完成!");
|
||||
LogManager::instance()->log("✓ 代码转换完成!");
|
||||
QMessageBox::information(this, "完成", "代码转换任务已成功完成!");
|
||||
} else {
|
||||
m_batchLogEdit->append(QString("✗ 转换失败! 退出码: %1").arg(exitCode));
|
||||
LogManager::instance()->logError(QString("✗ 转换失败! 退出码: %1").arg(exitCode));
|
||||
QMessageBox::warning(this, "失败", QString("代码转换任务失败,退出码: %1").arg(exitCode));
|
||||
}
|
||||
m_batchLogEdit->append("========================================");
|
||||
LogManager::instance()->log("========================================");
|
||||
}
|
||||
|
||||
void MainWindow::onPythonRunnerOutput(const QString &output)
|
||||
{
|
||||
if (!output.trimmed().isEmpty()) {
|
||||
m_batchLogEdit->append(output);
|
||||
LogManager::instance()->log(output);
|
||||
|
||||
QString trimmedOutput = output.trimmed();
|
||||
|
||||
QRegularExpression progressRegExp(R"(progress\s*[:=]\s*(\d+))");
|
||||
QRegularExpressionMatch match = progressRegExp.match(trimmedOutput);
|
||||
if (match.hasMatch()) {
|
||||
int progress = match.captured(1).toInt();
|
||||
QString status = trimmedOutput;
|
||||
if (status.contains("progress", Qt::CaseInsensitive)) {
|
||||
status = status.replace(progressRegExp, "").trimmed();
|
||||
if (status.isEmpty()) {
|
||||
status = QString("转换中 %1%").arg(progress);
|
||||
}
|
||||
}
|
||||
if (m_batchConvertPage) {
|
||||
m_batchConvertPage->onProgressUpdate(progress, status);
|
||||
}
|
||||
} else {
|
||||
if (m_batchConvertPage) {
|
||||
QString currentFunction;
|
||||
QRegularExpression funcRegExp(R"(([\w_]+))");
|
||||
QRegularExpressionMatch funcMatch = funcRegExp.match(trimmedOutput);
|
||||
if (funcMatch.hasMatch()) {
|
||||
currentFunction = funcMatch.captured(1);
|
||||
}
|
||||
|
||||
if (!currentFunction.isEmpty() && m_totalFunctions > 0) {
|
||||
int index = m_functionList.indexOf(currentFunction);
|
||||
if (index >= 0 && index >= m_currentFunctionIndex) {
|
||||
m_currentFunctionIndex = index + 1;
|
||||
int progress = 20 + (m_currentFunctionIndex * 80) / m_totalFunctions;
|
||||
QString status = QString("正在转换: %1").arg(currentFunction);
|
||||
m_batchConvertPage->onProgressUpdate(progress, status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int currentProgress = 20;
|
||||
if (trimmedOutput.contains("开始转换", Qt::CaseInsensitive)) {
|
||||
currentProgress = 25;
|
||||
} else if (trimmedOutput.contains("处理文件", Qt::CaseInsensitive)) {
|
||||
currentProgress = 30;
|
||||
} else if (trimmedOutput.contains("生成代码", Qt::CaseInsensitive)) {
|
||||
currentProgress = 75;
|
||||
} else if (trimmedOutput.contains("完成", Qt::CaseInsensitive)) {
|
||||
currentProgress = 95;
|
||||
}
|
||||
m_batchConvertPage->onProgressUpdate(currentProgress, trimmedOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onPythonRunnerError(const QString &error)
|
||||
{
|
||||
if (!error.trimmed().isEmpty()) {
|
||||
m_batchLogEdit->append(QString("[ERROR] %1").arg(error));
|
||||
LogManager::instance()->logError(QString("[ERROR] %1").arg(error));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#include "ElaWindow.h"
|
||||
#include "ElaToolButton.h"
|
||||
#include <QWidget>
|
||||
#include <QTextEdit>
|
||||
#include "src/pythonrunner/PythonRunner.h"
|
||||
#include "src/pages/batchconvert/batchconvertpage.h"
|
||||
#include "src/pages/functionsearch/functionsearchpage.h"
|
||||
|
|
@ -30,7 +29,10 @@ private:
|
|||
QWidget* createAboutPage();
|
||||
QWidget* createSettingsPage();
|
||||
|
||||
void loadConfigCache();
|
||||
|
||||
void onBatchConvertStart();
|
||||
void onBatchConvertStop();
|
||||
void onPythonRunnerFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void onPythonRunnerOutput(const QString &output);
|
||||
void onPythonRunnerError(const QString &error);
|
||||
|
|
@ -40,10 +42,14 @@ private:
|
|||
void onNavigationButtonClicked();
|
||||
|
||||
PythonRunner *m_pythonRunner;
|
||||
QTextEdit *m_batchLogEdit;
|
||||
bool m_iconsSet;
|
||||
ElaToolButton* m_navigationButton;
|
||||
bool m_isNavigationExpanded;
|
||||
BatchConvertPage *m_batchConvertPage;
|
||||
|
||||
int m_totalFunctions;
|
||||
int m_currentFunctionIndex;
|
||||
QStringList m_functionList;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#include "batchconvertpage.h"
|
||||
#include "src/utils/uf2configreader.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
|
@ -12,6 +13,7 @@
|
|||
#include <QInputDialog>
|
||||
#include <QDialog>
|
||||
#include <QTextEdit>
|
||||
#include "src/utils/logmanager.h"
|
||||
|
||||
BatchConvertPage::BatchConvertPage(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
|
|
@ -63,37 +65,62 @@ void BatchConvertPage::initUI()
|
|||
|
||||
layout->addWidget(funcBox);
|
||||
|
||||
QHBoxLayout *btnLayout = new QHBoxLayout;
|
||||
QPushButton *startBtn = new QPushButton("开始转换");
|
||||
startBtn->setStyleSheet("background-color: #1abc9c; color: white; padding: 10px 30px; font-size: 14px; border: none; border-radius: 4px;");
|
||||
connect(startBtn, &QPushButton::clicked, this, &BatchConvertPage::onStartConvert);
|
||||
QPushButton *clearLogBtn = new QPushButton("清空日志");
|
||||
connect(clearLogBtn, &QPushButton::clicked, this, &BatchConvertPage::onClearLog);
|
||||
btnLayout->addStretch();
|
||||
btnLayout->addWidget(startBtn);
|
||||
btnLayout->addWidget(clearLogBtn);
|
||||
layout->addLayout(btnLayout);
|
||||
QGroupBox *progressBox = new QGroupBox("转换进度");
|
||||
progressBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
QVBoxLayout *progressLayout = new QVBoxLayout(progressBox);
|
||||
progressLayout->setSpacing(10);
|
||||
|
||||
m_logEdit = new QTextEdit;
|
||||
m_logEdit->setReadOnly(true);
|
||||
m_logEdit->setStyleSheet("background-color: #2c3e50; color: #ecf0f1;");
|
||||
m_logEdit->append("转码工具已准备就绪...");
|
||||
layout->addWidget(m_logEdit);
|
||||
m_progressLabel = new QLabel("等待开始...");
|
||||
m_progressLabel->setStyleSheet("color: #666;");
|
||||
m_progressLabel->setFixedHeight(20);
|
||||
m_progressLabel->setWordWrap(false);
|
||||
m_progressLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
progressLayout->addWidget(m_progressLabel);
|
||||
|
||||
m_progressBar = new QProgressBar;
|
||||
m_progressBar->setRange(0, 100);
|
||||
m_progressBar->setValue(0);
|
||||
m_progressBar->setFixedHeight(25);
|
||||
m_progressBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
m_progressBar->setStyleSheet(R"(
|
||||
QProgressBar {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
background-color: #f0f0f0;
|
||||
text-align: center;
|
||||
}
|
||||
QProgressBar::chunk {
|
||||
background-color: #1abc9c;
|
||||
border-radius: 4px;
|
||||
}
|
||||
)");
|
||||
progressLayout->addWidget(m_progressBar);
|
||||
|
||||
layout->addWidget(progressBox);
|
||||
|
||||
QHBoxLayout *btnLayout = new QHBoxLayout;
|
||||
m_startBtn = new QPushButton("开始转换");
|
||||
m_startBtn->setStyleSheet("background-color: #1abc9c; color: white; padding: 10px 30px; font-size: 14px; border: none; border-radius: 4px;");
|
||||
connect(m_startBtn, &QPushButton::clicked, this, &BatchConvertPage::onStartConvert);
|
||||
btnLayout->addStretch();
|
||||
btnLayout->addWidget(m_startBtn);
|
||||
layout->addLayout(btnLayout);
|
||||
}
|
||||
|
||||
void BatchConvertPage::onProgressUpdate(int progress, const QString& status)
|
||||
{
|
||||
m_progressBar->setValue(progress);
|
||||
|
||||
QString displayStatus = status;
|
||||
if (displayStatus.length() > 80) {
|
||||
displayStatus = displayStatus.left(80) + "...";
|
||||
}
|
||||
m_progressLabel->setText(displayStatus);
|
||||
}
|
||||
|
||||
bool BatchConvertPage::checkFunctionExists(const QString &funcName)
|
||||
{
|
||||
QString jsonPath = QCoreApplication::applicationDirPath() + "/uf2touft3/cust.json";
|
||||
QFile file(jsonPath);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data = file.readAll();
|
||||
file.close();
|
||||
|
||||
QString content = QString::fromUtf8(data);
|
||||
return content.contains("\"" + funcName + "\"");
|
||||
return UF2ConfigReader::checkFuncExistsStatic(funcName);
|
||||
}
|
||||
|
||||
void BatchConvertPage::updateTable()
|
||||
|
|
@ -123,15 +150,15 @@ void BatchConvertPage::updateTable()
|
|||
}
|
||||
m_funcTable->setItem(i, 1, statusItem);
|
||||
|
||||
QPushButton *delBtn = new QPushButton;
|
||||
delBtn->setIcon(QIcon(":/resources/images/delect.png"));
|
||||
delBtn->setIconSize(QSize(20, 20));
|
||||
delBtn->setStyleSheet("padding: 2px; border: none; background-color: transparent;");
|
||||
delBtn->setToolTip("删除");
|
||||
connect(delBtn, &QPushButton::clicked, this, [this, i]() {
|
||||
onDeleteRow(i);
|
||||
QPushButton *editBtn = new QPushButton;
|
||||
editBtn->setIcon(QIcon(":/resources/images/bianji.png"));
|
||||
editBtn->setIconSize(QSize(20, 20));
|
||||
editBtn->setStyleSheet("padding: 2px; border: none; background-color: transparent;");
|
||||
editBtn->setToolTip("修改");
|
||||
connect(editBtn, &QPushButton::clicked, this, [this, i]() {
|
||||
onEditRow(i);
|
||||
});
|
||||
m_funcTable->setCellWidget(i, 2, delBtn);
|
||||
m_funcTable->setCellWidget(i, 2, editBtn);
|
||||
}
|
||||
|
||||
int totalWidth = m_funcTable->width();
|
||||
|
|
@ -151,12 +178,47 @@ void BatchConvertPage::resizeEvent(QResizeEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
void BatchConvertPage::onDeleteRow(int row)
|
||||
void BatchConvertPage::onEditRow(int row)
|
||||
{
|
||||
if (row >= 0 && row < m_funcList.size()) {
|
||||
m_funcList.removeAt(row);
|
||||
updateTable();
|
||||
if (row < 0 || row >= m_funcList.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString oldName = m_funcList[row];
|
||||
QString newName = oldName;
|
||||
|
||||
while (true) {
|
||||
QInputDialog dialog(this);
|
||||
dialog.setWindowTitle("修改函数名");
|
||||
dialog.setLabelText("请输入新的函数名:");
|
||||
dialog.setTextValue(oldName);
|
||||
dialog.resize(300, 150);
|
||||
|
||||
if (dialog.exec() != QDialog::Accepted) {
|
||||
return;
|
||||
}
|
||||
|
||||
newName = dialog.textValue().trimmed();
|
||||
|
||||
if (newName.isEmpty()) {
|
||||
QMessageBox::warning(this, "提示", "函数名不能为空!");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newName == oldName) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_funcList.contains(newName)) {
|
||||
QMessageBox::warning(this, "提示", "该函数名已存在,请重新输入!");
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
m_funcList[row] = newName;
|
||||
updateTable();
|
||||
}
|
||||
|
||||
void BatchConvertPage::onAddFunction()
|
||||
|
|
@ -264,7 +326,7 @@ bool BatchConvertPage::saveToCustJson(const QStringList &funcList)
|
|||
|
||||
QFile file(jsonPath);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
m_logEdit->append("[ERROR] 无法打开文件: " + jsonPath);
|
||||
LogManager::instance()->logError(QString("无法打开文件: %1").arg(jsonPath));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -278,7 +340,7 @@ bool BatchConvertPage::saveToCustJson(const QStringList &funcList)
|
|||
dirStart = content.indexOf("\"dir\" : [");
|
||||
}
|
||||
if (dirStart < 0) {
|
||||
m_logEdit->append("[ERROR] 未找到 \"dir\" 节点");
|
||||
LogManager::instance()->logError("未找到 \"dir\" 节点");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -302,7 +364,7 @@ bool BatchConvertPage::saveToCustJson(const QStringList &funcList)
|
|||
content.replace(arrayStart, arrayEnd - arrayStart, newDirArray);
|
||||
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
m_logEdit->append("[ERROR] 无法写入文件: " + jsonPath);
|
||||
LogManager::instance()->logError(QString("无法写入文件: %1").arg(jsonPath));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -314,33 +376,54 @@ bool BatchConvertPage::saveToCustJson(const QStringList &funcList)
|
|||
|
||||
void BatchConvertPage::onStartConvert()
|
||||
{
|
||||
if (m_funcList.isEmpty()) {
|
||||
m_logEdit->append("请先添加需要转码的函数!");
|
||||
if (m_startBtn->text() == "停止转换") {
|
||||
LogManager::instance()->log("用户请求停止转换...");
|
||||
m_progressLabel->setText("正在停止转换...");
|
||||
emit stopConvert();
|
||||
return;
|
||||
}
|
||||
|
||||
m_logEdit->append("========================================");
|
||||
m_logEdit->append("正在写入 cust.json ...");
|
||||
m_logEdit->append("功能列表:");
|
||||
if (m_funcList.isEmpty()) {
|
||||
QMessageBox::warning(this, "提示", "请先添加需要转码的函数!");
|
||||
return;
|
||||
}
|
||||
|
||||
m_progressBar->setValue(0);
|
||||
m_progressLabel->setText("正在准备转换...");
|
||||
|
||||
LogManager::instance()->log("========================================");
|
||||
LogManager::instance()->log("正在写入 cust.json ...");
|
||||
LogManager::instance()->log("功能列表:");
|
||||
|
||||
for (const QString &func : m_funcList) {
|
||||
m_logEdit->append(" - " + func + ".service_design");
|
||||
LogManager::instance()->log(QString(" - %1.service_design").arg(func));
|
||||
}
|
||||
|
||||
if (saveToCustJson(m_funcList)) {
|
||||
m_logEdit->append("[OK] cust.json 写入成功!");
|
||||
LogManager::instance()->log("cust.json 写入成功!");
|
||||
m_progressLabel->setText("配置加载成功,开始转换...");
|
||||
m_progressBar->setValue(20);
|
||||
} else {
|
||||
m_logEdit->append("[FAIL] cust.json 写入失败!");
|
||||
m_logEdit->append("========================================");
|
||||
LogManager::instance()->logError("cust.json 写入失败!");
|
||||
LogManager::instance()->log("========================================");
|
||||
m_progressLabel->setText("配置加载失败");
|
||||
return;
|
||||
}
|
||||
|
||||
m_logEdit->append("========================================");
|
||||
LogManager::instance()->log("========================================");
|
||||
emit startConvert();
|
||||
}
|
||||
|
||||
void BatchConvertPage::onClearLog()
|
||||
void BatchConvertPage::onConvertStarted()
|
||||
{
|
||||
m_logEdit->clear();
|
||||
m_logEdit->append("转码工具已准备就绪...");
|
||||
}
|
||||
m_startBtn->setText("停止转换");
|
||||
m_startBtn->setStyleSheet("background-color: #e74c3c; color: white; padding: 10px 30px; font-size: 14px; border: none; border-radius: 4px;");
|
||||
}
|
||||
|
||||
void BatchConvertPage::onConvertFinished()
|
||||
{
|
||||
m_progressBar->setValue(100);
|
||||
m_progressLabel->setText("转换完成");
|
||||
m_startBtn->setText("开始转换");
|
||||
m_startBtn->setStyleSheet("background-color: #1abc9c; color: white; padding: 10px 30px; font-size: 14px; border: none; border-radius: 4px;");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@
|
|||
|
||||
#include <QWidget>
|
||||
#include <QLineEdit>
|
||||
#include <QTextEdit>
|
||||
#include <QTableWidget>
|
||||
#include <QPushButton>
|
||||
#include <QProgressBar>
|
||||
#include <QLabel>
|
||||
|
||||
class BatchConvertPage : public QWidget
|
||||
{
|
||||
|
|
@ -15,18 +16,24 @@ public:
|
|||
explicit BatchConvertPage(QWidget *parent = nullptr);
|
||||
~BatchConvertPage();
|
||||
|
||||
QTextEdit* getLogEdit() { return m_logEdit; }
|
||||
|
||||
signals:
|
||||
void startConvert();
|
||||
void stopConvert();
|
||||
|
||||
public slots:
|
||||
void onProgressUpdate(int progress, const QString& status);
|
||||
void onConvertFinished();
|
||||
void onConvertStarted();
|
||||
|
||||
int getFunctionCount() const { return m_funcList.size(); }
|
||||
QStringList getFunctionList() const { return m_funcList; }
|
||||
|
||||
private slots:
|
||||
void onStartConvert();
|
||||
void onClearLog();
|
||||
void onAddFunction();
|
||||
void onRemoveFunction();
|
||||
void onClearTable();
|
||||
void onDeleteRow(int row);
|
||||
void onEditRow(int row);
|
||||
|
||||
private:
|
||||
void initUI();
|
||||
|
|
@ -36,8 +43,10 @@ private:
|
|||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
QTableWidget *m_funcTable;
|
||||
QTextEdit *m_logEdit;
|
||||
QStringList m_funcList;
|
||||
QProgressBar *m_progressBar;
|
||||
QLabel *m_progressLabel;
|
||||
QPushButton *m_startBtn;
|
||||
};
|
||||
|
||||
#endif // BATCHCONVERTPAGE_H
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,365 @@
|
|||
#include "datacache.h"
|
||||
#include "logmanager.h"
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlError>
|
||||
#include <QJsonDocument>
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QDateTime>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
DataCache* DataCache::m_instance = nullptr;
|
||||
|
||||
DataCache::DataCache(QObject *parent) : QObject(parent), m_dataLoaded(false)
|
||||
{
|
||||
}
|
||||
|
||||
DataCache::~DataCache()
|
||||
{
|
||||
if (m_db.isOpen()) {
|
||||
m_db.close();
|
||||
}
|
||||
}
|
||||
|
||||
DataCache* DataCache::instance()
|
||||
{
|
||||
if (!m_instance) {
|
||||
m_instance = new DataCache();
|
||||
}
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
QString DataCache::getDatabasePath()
|
||||
{
|
||||
QString appDir = QCoreApplication::applicationDirPath();
|
||||
QDir dbDir(appDir + "/cache");
|
||||
if (!dbDir.exists()) {
|
||||
if (!dbDir.mkpath(dbDir.absolutePath())) {
|
||||
LogManager::instance()->logError(QString("数据缓存 - 创建缓存目录失败: %1").arg(dbDir.absolutePath()));
|
||||
}
|
||||
}
|
||||
return dbDir.absoluteFilePath("config_cache.db");
|
||||
}
|
||||
|
||||
bool DataCache::createTables()
|
||||
{
|
||||
QSqlQuery query(m_db);
|
||||
|
||||
query.exec("PRAGMA synchronous = OFF");
|
||||
query.exec("PRAGMA journal_mode = MEMORY");
|
||||
|
||||
QString createUF20Table = R"(
|
||||
CREATE TABLE IF NOT EXISTS uf20_cname_table (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
cname TEXT UNIQUE NOT NULL,
|
||||
e_name TEXT,
|
||||
function_no TEXT,
|
||||
update_time TEXT NOT NULL
|
||||
)
|
||||
)";
|
||||
|
||||
QString createUFT3Table = R"(
|
||||
CREATE TABLE IF NOT EXISTS uft3_cname_table (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
cname TEXT UNIQUE NOT NULL,
|
||||
e_name TEXT,
|
||||
function_no TEXT,
|
||||
update_time TEXT NOT NULL
|
||||
)
|
||||
)";
|
||||
|
||||
if (!query.exec(createUF20Table)) {
|
||||
LogManager::instance()->logError(QString("数据缓存 - 创建uf20_cname_table失败: %1").arg(query.lastError().text()));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!query.exec(createUFT3Table)) {
|
||||
LogManager::instance()->logError(QString("数据缓存 - 创建uft3_cname_table失败: %1").arg(query.lastError().text()));
|
||||
return false;
|
||||
}
|
||||
|
||||
LogManager::instance()->log("数据缓存 - 表创建成功");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DataCache::initDatabase()
|
||||
{
|
||||
QString dbPath = getDatabasePath();
|
||||
LogManager::instance()->log(QString("数据缓存 - 数据库路径: %1").arg(dbPath));
|
||||
|
||||
if (QSqlDatabase::contains("qt_sql_default_connection")) {
|
||||
m_db = QSqlDatabase::database("qt_sql_default_connection");
|
||||
if (m_db.isOpen()) {
|
||||
LogManager::instance()->log("数据缓存 - 数据库已打开");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
m_db = QSqlDatabase::addDatabase("QSQLITE");
|
||||
m_db.setDatabaseName(dbPath);
|
||||
|
||||
if (!m_db.open()) {
|
||||
LogManager::instance()->logError(QString("数据缓存 - 打开数据库失败: %1").arg(m_db.lastError().text()));
|
||||
QString drivers = QSqlDatabase::drivers().join(", ");
|
||||
LogManager::instance()->logError(QString("数据缓存 - 可用的数据库驱动: %1").arg(drivers));
|
||||
return false;
|
||||
}
|
||||
|
||||
m_db.exec("PRAGMA synchronous = OFF");
|
||||
m_db.exec("PRAGMA journal_mode = MEMORY");
|
||||
|
||||
LogManager::instance()->log("数据缓存 - 数据库打开成功");
|
||||
return createTables();
|
||||
}
|
||||
|
||||
bool DataCache::isDataLoaded() const
|
||||
{
|
||||
return m_dataLoaded;
|
||||
}
|
||||
|
||||
void DataCache::setDataLoaded(bool loaded)
|
||||
{
|
||||
m_dataLoaded = loaded;
|
||||
}
|
||||
|
||||
bool DataCache::saveUF20Config(const QString& fileName, const QJsonObject& data)
|
||||
{
|
||||
if (!m_db.isOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileName != "uf2.json") {
|
||||
return true;
|
||||
}
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
query.exec("DELETE FROM uf20_cname_table");
|
||||
|
||||
QStringList cnames;
|
||||
QStringList eNames;
|
||||
QStringList functionNos;
|
||||
|
||||
for (auto it = data.begin(); it != data.end(); ++it) {
|
||||
if (it.value().isObject()) {
|
||||
QJsonObject obj = it.value().toObject();
|
||||
QString cname = obj.value("cname").toString();
|
||||
if (!cname.isEmpty()) {
|
||||
cnames.append(cname);
|
||||
eNames.append(obj.value("eName").toString());
|
||||
functionNos.append(obj.value("function_no").toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cnames.isEmpty()) {
|
||||
LogManager::instance()->logWarning("数据缓存 - UF20没有找到cname记录");
|
||||
return true;
|
||||
}
|
||||
|
||||
m_db.transaction();
|
||||
|
||||
query.prepare("INSERT INTO uf20_cname_table (cname, e_name, function_no, update_time) VALUES (?, ?, ?, ?)");
|
||||
|
||||
QString updateTime = QDateTime::currentDateTime().toString(Qt::ISODate);
|
||||
for (int i = 0; i < cnames.size(); ++i) {
|
||||
query.addBindValue(cnames[i]);
|
||||
query.addBindValue(eNames[i]);
|
||||
query.addBindValue(functionNos[i]);
|
||||
query.addBindValue(updateTime);
|
||||
query.exec();
|
||||
}
|
||||
|
||||
m_db.commit();
|
||||
|
||||
LogManager::instance()->logInfo(QString("数据缓存 - UF20成功保存 %1 个cname记录,耗时: %2ms").arg(cnames.size()).arg(timer.elapsed()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DataCache::saveUFT3Config(const QString& fileName, const QJsonObject& data)
|
||||
{
|
||||
if (!m_db.isOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileName != "uft3.json") {
|
||||
return true;
|
||||
}
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
query.exec("DELETE FROM uft3_cname_table");
|
||||
|
||||
QStringList cnames;
|
||||
QStringList eNames;
|
||||
QStringList functionNos;
|
||||
|
||||
for (auto it = data.begin(); it != data.end(); ++it) {
|
||||
if (it.value().isObject()) {
|
||||
QJsonObject obj = it.value().toObject();
|
||||
QString cname = obj.value("cname").toString();
|
||||
if (!cname.isEmpty()) {
|
||||
cnames.append(cname);
|
||||
eNames.append(obj.value("eName").toString());
|
||||
functionNos.append(obj.value("function_no").toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cnames.isEmpty()) {
|
||||
LogManager::instance()->logWarning("数据缓存 - UFT3没有找到cname记录");
|
||||
return true;
|
||||
}
|
||||
|
||||
m_db.transaction();
|
||||
|
||||
query.prepare("INSERT INTO uft3_cname_table (cname, e_name, function_no, update_time) VALUES (?, ?, ?, ?)");
|
||||
|
||||
QString updateTime = QDateTime::currentDateTime().toString(Qt::ISODate);
|
||||
for (int i = 0; i < cnames.size(); ++i) {
|
||||
query.addBindValue(cnames[i]);
|
||||
query.addBindValue(eNames[i]);
|
||||
query.addBindValue(functionNos[i]);
|
||||
query.addBindValue(updateTime);
|
||||
query.exec();
|
||||
}
|
||||
|
||||
m_db.commit();
|
||||
|
||||
LogManager::instance()->logInfo(QString("数据缓存 - UFT3成功保存 %1 个cname记录,耗时: %2ms").arg(cnames.size()).arg(timer.elapsed()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DataCache::hasUF20Config(const QString& fileName)
|
||||
{
|
||||
if (!m_db.isOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileName != "uf2.json") {
|
||||
return true;
|
||||
}
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
if (query.exec("SELECT COUNT(*) FROM uf20_cname_table")) {
|
||||
if (query.next()) {
|
||||
return query.value(0).toInt() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DataCache::hasUFT3Config(const QString& fileName)
|
||||
{
|
||||
if (!m_db.isOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileName != "uft3.json") {
|
||||
return true;
|
||||
}
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
if (query.exec("SELECT COUNT(*) FROM uft3_cname_table")) {
|
||||
if (query.next()) {
|
||||
return query.value(0).toInt() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DataCache::checkUF20CnameExists(const QString& cname)
|
||||
{
|
||||
if (!m_db.isOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
query.prepare("SELECT COUNT(*) FROM uf20_cname_table WHERE cname = :cname");
|
||||
query.bindValue(":cname", cname);
|
||||
|
||||
if (query.exec() && query.next()) {
|
||||
return query.value(0).toInt() > 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QSet<QString> DataCache::getAllUF20Cnames()
|
||||
{
|
||||
QSet<QString> result;
|
||||
|
||||
if (!m_db.isOpen()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
if (query.exec("SELECT cname FROM uf20_cname_table")) {
|
||||
while (query.next()) {
|
||||
result.insert(query.value(0).toString());
|
||||
}
|
||||
}
|
||||
|
||||
LogManager::instance()->logInfo(QString("数据缓存 - 获取UF20 Cname缓存,耗时: %1ms").arg(timer.elapsed()));
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DataCache::checkUFT3CnameExists(const QString& cname)
|
||||
{
|
||||
if (!m_db.isOpen()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
query.prepare("SELECT COUNT(*) FROM uft3_cname_table WHERE cname = :cname");
|
||||
query.bindValue(":cname", cname);
|
||||
|
||||
if (query.exec() && query.next()) {
|
||||
return query.value(0).toInt() > 0;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QSet<QString> DataCache::getAllUFT3Cnames()
|
||||
{
|
||||
QSet<QString> result;
|
||||
|
||||
if (!m_db.isOpen()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
if (query.exec("SELECT cname FROM uft3_cname_table")) {
|
||||
while (query.next()) {
|
||||
result.insert(query.value(0).toString());
|
||||
}
|
||||
}
|
||||
|
||||
LogManager::instance()->logInfo(QString("数据缓存 - 获取UFT3 Cname缓存,耗时: %1ms").arg(timer.elapsed()));
|
||||
return result;
|
||||
}
|
||||
|
||||
void DataCache::clearCache()
|
||||
{
|
||||
if (!m_db.isOpen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
query.exec("DELETE FROM uf20_cname_table");
|
||||
query.exec("DELETE FROM uft3_cname_table");
|
||||
m_dataLoaded = false;
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef DATACACHE_H
|
||||
#define DATACACHE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSqlDatabase>
|
||||
#include <QJsonObject>
|
||||
#include <QSet>
|
||||
|
||||
class DataCache : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static DataCache* instance();
|
||||
|
||||
bool initDatabase();
|
||||
bool isDataLoaded() const;
|
||||
void setDataLoaded(bool loaded);
|
||||
|
||||
bool saveUF20Config(const QString& fileName, const QJsonObject& data);
|
||||
bool saveUFT3Config(const QString& fileName, const QJsonObject& data);
|
||||
|
||||
bool hasUF20Config(const QString& fileName);
|
||||
bool hasUFT3Config(const QString& fileName);
|
||||
|
||||
bool checkUF20CnameExists(const QString& cname);
|
||||
QSet<QString> getAllUF20Cnames();
|
||||
|
||||
bool checkUFT3CnameExists(const QString& cname);
|
||||
QSet<QString> getAllUFT3Cnames();
|
||||
|
||||
void clearCache();
|
||||
|
||||
private:
|
||||
explicit DataCache(QObject *parent = nullptr);
|
||||
~DataCache();
|
||||
|
||||
bool createTables();
|
||||
QString getDatabasePath();
|
||||
|
||||
static DataCache* m_instance;
|
||||
QSqlDatabase m_db;
|
||||
bool m_dataLoaded;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
#include "logmanager.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
|
||||
LogManager* LogManager::m_instance = nullptr;
|
||||
|
||||
LogManager::LogManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
LogManager::~LogManager()
|
||||
{
|
||||
if (m_logFile.isOpen()) {
|
||||
m_logFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
LogManager* LogManager::instance()
|
||||
{
|
||||
if (!m_instance) {
|
||||
m_instance = new LogManager();
|
||||
}
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
void LogManager::initLogFile()
|
||||
{
|
||||
QString appDir = QCoreApplication::applicationDirPath();
|
||||
QDir logDir(appDir + "/logs");
|
||||
if (!logDir.exists()) {
|
||||
logDir.mkpath(".");
|
||||
}
|
||||
|
||||
QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd");
|
||||
m_logFilePath = logDir.absoluteFilePath(QString("uft3_change_code_%1.log").arg(timestamp));
|
||||
|
||||
m_logFile.setFileName(m_logFilePath);
|
||||
if (!m_logFile.open(QIODevice::Append | QIODevice::Text)) {
|
||||
qDebug() << "无法打开日志文件:" << m_logFilePath;
|
||||
return;
|
||||
}
|
||||
|
||||
writeLog("INFO", "日志系统初始化完成");
|
||||
}
|
||||
|
||||
QString LogManager::getLogFilePath() const
|
||||
{
|
||||
return m_logFilePath;
|
||||
}
|
||||
|
||||
void LogManager::writeLog(const QString& level, const QString& message)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss");
|
||||
QString logLine = QString("[%1] [%2] %3\n").arg(timestamp, level, message);
|
||||
|
||||
if (m_logFile.isOpen()) {
|
||||
QTextStream stream(&m_logFile);
|
||||
stream << logLine;
|
||||
stream.flush();
|
||||
}
|
||||
|
||||
if (level == "ERROR") {
|
||||
qCritical() << message;
|
||||
} else if (level == "WARNING") {
|
||||
qWarning() << message;
|
||||
} else {
|
||||
qDebug() << message;
|
||||
}
|
||||
}
|
||||
|
||||
void LogManager::log(const QString& message)
|
||||
{
|
||||
writeLog("INFO", message);
|
||||
}
|
||||
|
||||
void LogManager::logInfo(const QString& message)
|
||||
{
|
||||
writeLog("INFO", message);
|
||||
}
|
||||
|
||||
void LogManager::logWarning(const QString& message)
|
||||
{
|
||||
writeLog("WARNING", message);
|
||||
}
|
||||
|
||||
void LogManager::logError(const QString& message)
|
||||
{
|
||||
writeLog("ERROR", message);
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef LOGMANAGER_H
|
||||
#define LOGMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QMutex>
|
||||
|
||||
class LogManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static LogManager* instance();
|
||||
|
||||
void initLogFile();
|
||||
void log(const QString& message);
|
||||
void logInfo(const QString& message);
|
||||
void logWarning(const QString& message);
|
||||
void logError(const QString& message);
|
||||
|
||||
QString getLogFilePath() const;
|
||||
|
||||
private:
|
||||
explicit LogManager(QObject *parent = nullptr);
|
||||
~LogManager();
|
||||
|
||||
void writeLog(const QString& level, const QString& message);
|
||||
|
||||
static LogManager* m_instance;
|
||||
QFile m_logFile;
|
||||
QMutex m_mutex;
|
||||
QString m_logFilePath;
|
||||
};
|
||||
|
||||
#endif // LOGMANAGER_H
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
#include "uf2configreader.h"
|
||||
#include "datacache.h"
|
||||
#include "logmanager.h"
|
||||
#include <QFile>
|
||||
#include <QJsonDocument>
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
|
||||
QSet<QString> UF2ConfigReader::m_cnameCache;
|
||||
bool UF2ConfigReader::m_cnameCacheLoaded = false;
|
||||
|
||||
UF2ConfigReader::UF2ConfigReader(QObject *parent) : QObject(parent), m_loaded(false)
|
||||
{
|
||||
}
|
||||
|
||||
QString UF2ConfigReader::getBinPath()
|
||||
{
|
||||
QString appDir = QCoreApplication::applicationDirPath();
|
||||
return appDir + "/uf2touft3";
|
||||
}
|
||||
|
||||
bool UF2ConfigReader::loadAllUF20Config()
|
||||
{
|
||||
m_failedFiles.clear();
|
||||
|
||||
if (!DataCache::instance()->initDatabase()) {
|
||||
LogManager::instance()->logError("UF20配置加载 - 数据库初始化失败");
|
||||
m_failedFiles.append("uf2.json");
|
||||
return false;
|
||||
}
|
||||
|
||||
QString binPath = getBinPath();
|
||||
QString filePath = binPath + "/uf2.json";
|
||||
|
||||
if (DataCache::instance()->hasUF20Config("uf2.json")) {
|
||||
LogManager::instance()->log("UF20配置加载 - 已缓存,跳过: uf2.json");
|
||||
} else {
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
LogManager::instance()->logError(QString("UF20配置加载 - 无法打开文件: %1").arg(filePath));
|
||||
m_failedFiles.append("uf2.json");
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data = file.readAll();
|
||||
QJsonDocument doc = QJsonDocument::fromJson(data);
|
||||
file.close();
|
||||
|
||||
if (doc.isNull() || !doc.isObject()) {
|
||||
LogManager::instance()->logError(QString("UF20配置加载 - JSON解析失败: %1").arg(filePath));
|
||||
m_failedFiles.append("uf2.json");
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject config = doc.object();
|
||||
if (!DataCache::instance()->saveUF20Config("uf2.json", config)) {
|
||||
LogManager::instance()->logError("UF20配置加载 - 保存失败: uf2.json");
|
||||
m_failedFiles.append("uf2.json");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogManager::instance()->log("UF20配置加载 - 成功: uf2.json");
|
||||
}
|
||||
|
||||
m_loaded = true;
|
||||
DataCache::instance()->setDataLoaded(true);
|
||||
LogManager::instance()->logInfo("UF20配置加载 - 全部加载完成");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList UF2ConfigReader::getFailedFiles() const
|
||||
{
|
||||
return m_failedFiles;
|
||||
}
|
||||
|
||||
bool UF2ConfigReader::reloadUF20Config()
|
||||
{
|
||||
QString binPath = getBinPath();
|
||||
QString filePath = binPath + "/uf2.json";
|
||||
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
LogManager::instance()->logError(QString("UF20配置加载 - 无法打开文件: %1").arg(filePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data = file.readAll();
|
||||
QJsonDocument doc = QJsonDocument::fromJson(data);
|
||||
file.close();
|
||||
|
||||
if (doc.isNull() || !doc.isObject()) {
|
||||
LogManager::instance()->logError(QString("UF20配置加载 - JSON解析失败: %1").arg(filePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject config = doc.object();
|
||||
if (!DataCache::instance()->saveUF20Config("uf2.json", config)) {
|
||||
LogManager::instance()->logError("UF20配置加载 - 保存失败: uf2.json");
|
||||
return false;
|
||||
}
|
||||
|
||||
clearCnameCache();
|
||||
LogManager::instance()->logInfo("UF20配置重新加载完成");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UF2ConfigReader::isUF20Loaded() const
|
||||
{
|
||||
return m_loaded;
|
||||
}
|
||||
|
||||
bool UF2ConfigReader::loadCnameCache()
|
||||
{
|
||||
if (m_cnameCacheLoaded) {
|
||||
return true;
|
||||
}
|
||||
|
||||
m_cnameCache.clear();
|
||||
|
||||
if (!DataCache::instance()->initDatabase()) {
|
||||
LogManager::instance()->logError("Cname缓存加载 - 数据库初始化失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cnameCache = DataCache::instance()->getAllUF20Cnames();
|
||||
m_cnameCacheLoaded = true;
|
||||
LogManager::instance()->logInfo(QString("Cname缓存加载完成,共加载 %1 个函数名").arg(m_cnameCache.size()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UF2ConfigReader::checkFuncExistsStatic(const QString& funcName)
|
||||
{
|
||||
if (!m_cnameCacheLoaded) {
|
||||
loadCnameCache();
|
||||
}
|
||||
|
||||
bool exists = m_cnameCache.contains(funcName);
|
||||
LogManager::instance()->log(QString("检查函数名 [%1] 是否存在: %2").arg(funcName).arg(exists ? "是" : "否"));
|
||||
return exists;
|
||||
}
|
||||
|
||||
bool UF2ConfigReader::checkFunctionExists(const QString& funcName)
|
||||
{
|
||||
return checkFuncExistsStatic(funcName);
|
||||
}
|
||||
|
||||
void UF2ConfigReader::clearCnameCache()
|
||||
{
|
||||
m_cnameCache.clear();
|
||||
m_cnameCacheLoaded = false;
|
||||
LogManager::instance()->logInfo("Cname缓存已清空");
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef UF2CONFIGREADER_H
|
||||
#define UF2CONFIGREADER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QJsonObject>
|
||||
#include <QSet>
|
||||
|
||||
class UF2ConfigReader : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit UF2ConfigReader(QObject *parent = nullptr);
|
||||
|
||||
bool loadAllUF20Config();
|
||||
bool reloadUF20Config();
|
||||
|
||||
bool isUF20Loaded() const;
|
||||
QStringList getFailedFiles() const;
|
||||
bool checkFunctionExists(const QString& funcName);
|
||||
static bool checkFuncExistsStatic(const QString& funcName);
|
||||
static void clearCnameCache();
|
||||
|
||||
private:
|
||||
static bool loadCnameCache();
|
||||
|
||||
QString getBinPath();
|
||||
|
||||
QStringList m_failedFiles;
|
||||
bool m_loaded;
|
||||
|
||||
static QSet<QString> m_cnameCache;
|
||||
static bool m_cnameCacheLoaded;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
#include "uft3configreader.h"
|
||||
#include "datacache.h"
|
||||
#include "logmanager.h"
|
||||
#include <QFile>
|
||||
#include <QJsonDocument>
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
|
||||
QSet<QString> UFT3ConfigReader::m_cnameCache;
|
||||
bool UFT3ConfigReader::m_cnameCacheLoaded = false;
|
||||
|
||||
UFT3ConfigReader::UFT3ConfigReader(QObject *parent) : QObject(parent), m_loaded(false)
|
||||
{
|
||||
}
|
||||
|
||||
QString UFT3ConfigReader::getBinPath()
|
||||
{
|
||||
QString appDir = QCoreApplication::applicationDirPath();
|
||||
return appDir + "/uf2touft3";
|
||||
}
|
||||
|
||||
bool UFT3ConfigReader::loadAllUFT3Config()
|
||||
{
|
||||
m_failedFiles.clear();
|
||||
|
||||
if (!DataCache::instance()->initDatabase()) {
|
||||
LogManager::instance()->logError("UFT3配置加载 - 数据库初始化失败");
|
||||
m_failedFiles.append("uft3.json");
|
||||
return false;
|
||||
}
|
||||
|
||||
QString binPath = getBinPath();
|
||||
QString filePath = binPath + "/uft3.json";
|
||||
|
||||
if (DataCache::instance()->hasUFT3Config("uft3.json")) {
|
||||
LogManager::instance()->log("UFT3配置加载 - 已缓存,跳过: uft3.json");
|
||||
} else {
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
LogManager::instance()->logError(QString("UFT3配置加载 - 无法打开文件: %1").arg(filePath));
|
||||
m_failedFiles.append("uft3.json");
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data = file.readAll();
|
||||
QJsonDocument doc = QJsonDocument::fromJson(data);
|
||||
file.close();
|
||||
|
||||
if (doc.isNull() || !doc.isObject()) {
|
||||
LogManager::instance()->logError(QString("UFT3配置加载 - JSON解析失败: %1").arg(filePath));
|
||||
m_failedFiles.append("uft3.json");
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject config = doc.object();
|
||||
if (!DataCache::instance()->saveUFT3Config("uft3.json", config)) {
|
||||
LogManager::instance()->logError("UFT3配置加载 - 保存失败: uft3.json");
|
||||
m_failedFiles.append("uft3.json");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogManager::instance()->log("UFT3配置加载 - 成功: uft3.json");
|
||||
}
|
||||
|
||||
m_loaded = true;
|
||||
DataCache::instance()->setDataLoaded(true);
|
||||
LogManager::instance()->logInfo("UFT3配置加载 - 全部加载完成");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QStringList UFT3ConfigReader::getFailedFiles() const
|
||||
{
|
||||
return m_failedFiles;
|
||||
}
|
||||
|
||||
bool UFT3ConfigReader::reloadUFT3Config()
|
||||
{
|
||||
QString binPath = getBinPath();
|
||||
QString filePath = binPath + "/uft3.json";
|
||||
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
LogManager::instance()->logError(QString("UFT3配置加载 - 无法打开文件: %1").arg(filePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray data = file.readAll();
|
||||
QJsonDocument doc = QJsonDocument::fromJson(data);
|
||||
file.close();
|
||||
|
||||
if (doc.isNull() || !doc.isObject()) {
|
||||
LogManager::instance()->logError(QString("UFT3配置加载 - JSON解析失败: %1").arg(filePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject config = doc.object();
|
||||
if (!DataCache::instance()->saveUFT3Config("uft3.json", config)) {
|
||||
LogManager::instance()->logError("UFT3配置加载 - 保存失败: uft3.json");
|
||||
return false;
|
||||
}
|
||||
|
||||
clearCnameCache();
|
||||
LogManager::instance()->logInfo("UFT3配置重新加载完成");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UFT3ConfigReader::isUFT3Loaded() const
|
||||
{
|
||||
return m_loaded;
|
||||
}
|
||||
|
||||
bool UFT3ConfigReader::loadCnameCache()
|
||||
{
|
||||
if (m_cnameCacheLoaded) {
|
||||
return true;
|
||||
}
|
||||
|
||||
m_cnameCache.clear();
|
||||
|
||||
if (!DataCache::instance()->initDatabase()) {
|
||||
LogManager::instance()->logError("UFT3 Cname缓存加载 - 数据库初始化失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cnameCache = DataCache::instance()->getAllUFT3Cnames();
|
||||
m_cnameCacheLoaded = true;
|
||||
LogManager::instance()->logInfo(QString("UFT3 Cname缓存加载完成,共加载 %1 个函数名").arg(m_cnameCache.size()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool UFT3ConfigReader::checkFuncExistsStatic(const QString& funcName)
|
||||
{
|
||||
if (!m_cnameCacheLoaded) {
|
||||
loadCnameCache();
|
||||
}
|
||||
|
||||
bool exists = m_cnameCache.contains(funcName);
|
||||
LogManager::instance()->log(QString("检查UFT3函数名 [%1] 是否存在: %2").arg(funcName).arg(exists ? "是" : "否"));
|
||||
return exists;
|
||||
}
|
||||
|
||||
bool UFT3ConfigReader::checkFunctionExists(const QString& funcName)
|
||||
{
|
||||
return checkFuncExistsStatic(funcName);
|
||||
}
|
||||
|
||||
void UFT3ConfigReader::clearCnameCache()
|
||||
{
|
||||
m_cnameCache.clear();
|
||||
m_cnameCacheLoaded = false;
|
||||
LogManager::instance()->logInfo("UFT3 Cname缓存已清空");
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef UFT3CONFIGREADER_H
|
||||
#define UFT3CONFIGREADER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QJsonObject>
|
||||
#include <QSet>
|
||||
|
||||
class UFT3ConfigReader : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit UFT3ConfigReader(QObject *parent = nullptr);
|
||||
|
||||
bool loadAllUFT3Config();
|
||||
bool reloadUFT3Config();
|
||||
|
||||
bool isUFT3Loaded() const;
|
||||
QStringList getFailedFiles() const;
|
||||
bool checkFunctionExists(const QString& funcName);
|
||||
static bool checkFuncExistsStatic(const QString& funcName);
|
||||
static void clearCnameCache();
|
||||
|
||||
private:
|
||||
static bool loadCnameCache();
|
||||
|
||||
QString getBinPath();
|
||||
|
||||
QStringList m_failedFiles;
|
||||
bool m_loaded;
|
||||
|
||||
static QSet<QString> m_cnameCache;
|
||||
static bool m_cnameCacheLoaded;
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Reference in New Issue