feat: 支持按策略生成 Git 标签清单

This commit is contained in:
2026-07-20 06:43:46 +00:00
parent fcd67e08aa
commit 1c8ec37d2b
8 changed files with 147 additions and 43 deletions
+1
View File
@@ -126,6 +126,7 @@ bool PolicyHelper::allowRun() const { return isValid() && m_policy.value("allow_
bool PolicyHelper::forceUpdate() const { return isValid() && m_policy.value("force_update").toBool(); } bool PolicyHelper::forceUpdate() const { return isValid() && m_policy.value("force_update").toBool(); }
bool PolicyHelper::allowRollback() const { return isValid() && m_policy.value("allow_rollback").toBool(); } bool PolicyHelper::allowRollback() const { return isValid() && m_policy.value("allow_rollback").toBool(); }
bool PolicyHelper::isOfflineAllowed() const { return isValid() && m_policy.value("offline_allowed").toBool(); } bool PolicyHelper::isOfflineAllowed() const { return isValid() && m_policy.value("offline_allowed").toBool(); }
bool PolicyHelper::gitTagsEnabled() const { return isValid() && m_policy.value("git_tags_enabled").toBool(); }
bool PolicyHelper::isExpired() const { bool PolicyHelper::isExpired() const {
if (!isValid()) return true; if (!isValid()) return true;
const QDateTime expiry = QDateTime::fromString(m_policy.value("valid_until").toString(), Qt::ISODate); const QDateTime expiry = QDateTime::fromString(m_policy.value("valid_until").toString(), Qt::ISODate);
+1
View File
@@ -17,6 +17,7 @@ public:
bool forceUpdate() const; bool forceUpdate() const;
bool allowRollback() const; bool allowRollback() const;
bool isOfflineAllowed() const; bool isOfflineAllowed() const;
bool gitTagsEnabled() const;
bool isExpired() const; bool isExpired() const;
qint64 policySeq() const; qint64 policySeq() const;
QString message() const; QString message() const;
+45
View File
@@ -160,6 +160,51 @@ bool UpdateLogic::cacheManifest(const QString& appId, const QString& channel, co
return true; return true;
} }
bool UpdateLogic::refreshGitTagsFile(const QString& outputPath)
{
m_error.clear();
if (m_serverAddr.isEmpty()) {
m_error = QCoreApplication::translate("UpdateLogic", "Server address is empty.");
return false;
}
QJsonObject response;
int statusCode = 0;
QJsonObject body;
body["app_id"] = m_appId;
body["channel"] = m_channel;
m_http.postRequest(m_serverAddr + "/api/v1/git/tags", body,
[&](int code, const QJsonObject& resp) {
statusCode = code;
response = resp;
});
if (statusCode != 200) {
const QJsonValue detail = response.value("detail");
const QString message = detail.isObject()
? detail.toObject().value("msg").toString()
: detail.toString();
m_error = message.isEmpty()
? QCoreApplication::translate("UpdateLogic", "Git tags request failed (HTTP %1).").arg(statusCode)
: message;
return false;
}
const QString tagsText = response.value("tags_text").toString();
if (tagsText.isEmpty()) {
m_error = QCoreApplication::translate("UpdateLogic", "Git tags response is empty.");
return false;
}
QString writeError;
if (!ConfigHelper::writeFileWithElevationIfNeeded(outputPath, tagsText.toUtf8(), &writeError)) {
m_error = QCoreApplication::translate("UpdateLogic", "Cannot write Git tags file: %1").arg(writeError);
return false;
}
qDebug() << "Git tags file refreshed:" << outputPath;
return true;
}
void UpdateLogic::reportUpdateResult(const QString& deviceId, const QString& fromVer, const QString& toVer, bool success) void UpdateLogic::reportUpdateResult(const QString& deviceId, const QString& fromVer, const QString& toVer, bool success)
{ {
QString url = m_serverAddr + "/api/v1/update/report"; QString url = m_serverAddr + "/api/v1/update/report";
+1
View File
@@ -15,6 +15,7 @@ public:
void reportUpdateResult(const QString& deviceId, const QString& fromVer, const QString& toVer, bool success); void reportUpdateResult(const QString& deviceId, const QString& fromVer, const QString& toVer, bool success);
bool cacheManifest(const QString& appId, const QString& channel, const QString& version, bool cacheManifest(const QString& appId, const QString& channel, const QString& version,
int versionId, const QString& cacheDir); int versionId, const QString& cacheDir);
bool refreshGitTagsFile(const QString& outputPath);
bool getNeedUpdate() const { return m_needUpdate; } bool getNeedUpdate() const { return m_needUpdate; }
QString getLatestVersion() const { return m_latestVer; } QString getLatestVersion() const { return m_latestVer; }
+16
View File
@@ -260,6 +260,22 @@ int main(int argc, char* argv[])
return -1; return -1;
} }
if (networkOk && policy.gitTagsEnabled())
{
progress.setLabelText(QCoreApplication::translate("Launcher", "Generating Git tag list..."));
QApplication::processEvents();
const QString tagsPath = QDir(appDir).filePath("tags.txt");
if (!logic.refreshGitTagsFile(tagsPath))
{
progress.close();
QMessageBox::warning(nullptr,
QCoreApplication::translate("Launcher", "Git Tag List Failed"),
QCoreApplication::translate("Launcher", "Cannot generate tags.txt, but startup will continue:\n%1").arg(logic.errorString()));
progress.show();
QApplication::processEvents();
}
}
if (networkOk && needUpdate) if (networkOk && needUpdate)
{ {
progress.close(); progress.close();
+1 -1
View File
@@ -1,3 +1,3 @@
{ {
"api_base_url": "http://192.168.1.158:8000" "api_base_url": "http://192.168.229.128:8000"
} }
Binary file not shown.
+63 -23
View File
@@ -280,7 +280,7 @@ Please enter a new License for %2:</source>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="186"/> <location filename="../Launcher/main.cpp" line="186"/>
<location filename="../Launcher/main.cpp" line="324"/> <location filename="../Launcher/main.cpp" line="340"/>
<source>Offline Update</source> <source>Offline Update</source>
<translation>线</translation> <translation>线</translation>
</message> </message>
@@ -343,110 +343,150 @@ Please enter a new License for %2:</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="267"/> <location filename="../Launcher/main.cpp" line="265"/>
<source>Generating Git tag list...</source>
<translation> Git ...</translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="272"/>
<source>Git Tag List Failed</source>
<translation>Git </translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="273"/>
<source>Cannot generate tags.txt, but startup will continue:
%1</source>
<translation> tags.txt
%1</translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="283"/>
<source>Version Rollback</source> <source>Version Rollback</source>
<translation>退</translation> <translation>退</translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="268"/> <location filename="../Launcher/main.cpp" line="284"/>
<source>Update Required</source> <source>Update Required</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="268"/> <location filename="../Launcher/main.cpp" line="284"/>
<source>New Version Available</source> <source>New Version Available</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="271"/> <location filename="../Launcher/main.cpp" line="287"/>
<source>The administrator provided version %1 as the rollback target. Downgrade now?</source> <source>The administrator provided version %1 as the rollback target. Downgrade now?</source>
<translation> %1 退</translation> <translation> %1 退</translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="272"/> <location filename="../Launcher/main.cpp" line="288"/>
<source>Version %1 is available. Update now?</source> <source>Version %1 is available. Update now?</source>
<translation> %1</translation> <translation> %1</translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="273"/> <location filename="../Launcher/main.cpp" line="289"/>
<source> <source>
Target version: %1</source> Target version: %1</source>
<translation> <translation>
%1</translation> %1</translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="284"/> <location filename="../Launcher/main.cpp" line="300"/>
<location filename="../Launcher/main.cpp" line="348"/> <location filename="../Launcher/main.cpp" line="364"/>
<source>Startup Failed</source> <source>Startup Failed</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="285"/> <location filename="../Launcher/main.cpp" line="301"/>
<location filename="../Launcher/main.cpp" line="349"/> <location filename="../Launcher/main.cpp" line="365"/>
<source>Cannot start the main application: %1</source> <source>Cannot start the main application: %1</source>
<translation>%1</translation> <translation>%1</translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="294"/> <location filename="../Launcher/main.cpp" line="310"/>
<source>Updater Startup Failed</source> <source>Updater Startup Failed</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="295"/> <location filename="../Launcher/main.cpp" line="311"/>
<source>Cannot start the updater: %1</source> <source>Cannot start the updater: %1</source>
<translation>%1</translation> <translation>%1</translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="303"/> <location filename="../Launcher/main.cpp" line="319"/>
<source>Caching signed version manifest...</source> <source>Caching signed version manifest...</source>
<translation>...</translation> <translation>...</translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="310"/> <location filename="../Launcher/main.cpp" line="326"/>
<source>Manifest Cache Failed</source> <source>Manifest Cache Failed</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="311"/> <location filename="../Launcher/main.cpp" line="327"/>
<source>Cannot cache the signed manifest for the current version: %1</source> <source>Cannot cache the signed manifest for the current version: %1</source>
<translation>%1</translation> <translation>%1</translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="319"/> <location filename="../Launcher/main.cpp" line="335"/>
<source>Server Unavailable</source> <source>Server Unavailable</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="320"/> <location filename="../Launcher/main.cpp" line="336"/>
<source>Cannot connect to the update server. Import an offline update package?</source> <source>Cannot connect to the update server. Import an offline update package?</source>
<translation>线</translation> <translation>线</translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="325"/> <location filename="../Launcher/main.cpp" line="341"/>
<source>No offline update package was selected, or the updater could not be started.</source> <source>No offline update package was selected, or the updater could not be started.</source>
<translation>线</translation> <translation>线</translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="335"/> <location filename="../Launcher/main.cpp" line="351"/>
<source>Network Unavailable</source> <source>Network Unavailable</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="336"/> <location filename="../Launcher/main.cpp" line="352"/>
<source>Cannot connect to the update server, and the current policy does not allow offline startup.</source> <source>Cannot connect to the update server, and the current policy does not allow offline startup.</source>
<translation>线</translation> <translation>线</translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="341"/> <location filename="../Launcher/main.cpp" line="357"/>
<source>The application is up to date. Starting...</source> <source>The application is up to date. Starting...</source>
<translation>...</translation> <translation>...</translation>
</message> </message>
<message> <message>
<location filename="../Launcher/main.cpp" line="342"/> <location filename="../Launcher/main.cpp" line="358"/>
<source>Offline mode is active. Starting...</source> <source>Offline mode is active. Starting...</source>
<translation>线...</translation> <translation>线...</translation>
</message> </message>
</context> </context>
<context>
<name>UpdateLogic</name>
<message>
<location filename="../Launcher/UpdateLogic.cpp" line="167"/>
<source>Server address is empty.</source>
<translation></translation>
</message>
<message>
<location filename="../Launcher/UpdateLogic.cpp" line="188"/>
<source>Git tags request failed (HTTP %1).</source>
<translation>Git HTTP %1</translation>
</message>
<message>
<location filename="../Launcher/UpdateLogic.cpp" line="195"/>
<source>Git tags response is empty.</source>
<translation>Git </translation>
</message>
<message>
<location filename="../Launcher/UpdateLogic.cpp" line="201"/>
<source>Cannot write Git tags file: %1</source>
<translation> Git %1</translation>
</message>
</context>
<context> <context>
<name>Updater</name> <name>Updater</name>
<message> <message>