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
+5 -4
View File
@@ -123,10 +123,11 @@ bool PolicyHelper::isVersionAllowed(const QString& version) const {
return true;
}
bool PolicyHelper::allowRun() const { return isValid() && m_policy.value("allow_run").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::isOfflineAllowed() const { return isValid() && m_policy.value("offline_allowed").toBool(); }
bool PolicyHelper::isExpired() const {
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::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 {
if (!isValid()) return true;
const QDateTime expiry = QDateTime::fromString(m_policy.value("valid_until").toString(), Qt::ISODate);
return !expiry.isValid() || QDateTime::currentDateTimeUtc() > expiry;
+4 -3
View File
@@ -15,9 +15,10 @@ public:
bool isVersionAllowed(const QString& currentVersion) const;
bool allowRun() const;
bool forceUpdate() const;
bool allowRollback() const;
bool isOfflineAllowed() const;
bool isExpired() const;
bool allowRollback() const;
bool isOfflineAllowed() const;
bool gitTagsEnabled() const;
bool isExpired() const;
qint64 policySeq() const;
QString message() const;
+52 -7
View File
@@ -101,8 +101,8 @@ void UpdateLogic::getDownloadUrl(const QString& appId, const QString& channel, c
});
}
bool UpdateLogic::cacheManifest(const QString& appId, const QString& channel, const QString& version,
int versionId, const QString& cacheDir)
bool UpdateLogic::cacheManifest(const QString& appId, const QString& channel, const QString& version,
int versionId, const QString& cacheDir)
{
m_error.clear();
if (appId.isEmpty() || channel.isEmpty() || version.isEmpty() || versionId <= 0) {
@@ -157,11 +157,56 @@ bool UpdateLogic::cacheManifest(const QString& appId, const QString& channel, co
return false;
}
qDebug() << "Current version manifest cached to" << file.fileName();
return true;
}
void UpdateLogic::reportUpdateResult(const QString& deviceId, const QString& fromVer, const QString& toVer, bool success)
{
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)
{
QString url = m_serverAddr + "/api/v1/update/report";
QJsonObject body;
body["app_id"] = m_appId;
+1
View File
@@ -15,6 +15,7 @@ public:
void reportUpdateResult(const QString& deviceId, const QString& fromVer, const QString& toVer, bool success);
bool cacheManifest(const QString& appId, const QString& channel, const QString& version,
int versionId, const QString& cacheDir);
bool refreshGitTagsFile(const QString& outputPath);
bool getNeedUpdate() const { return m_needUpdate; }
QString getLatestVersion() const { return m_latestVer; }
+21 -5
View File
@@ -251,15 +251,31 @@ int main(int argc, char* argv[])
QCoreApplication::translate("Launcher", "A version policy sequence rollback was detected. Startup has been blocked."));
return -1;
}
if (state.isSystemTimeRewound())
{
progress.close();
if (state.isSystemTimeRewound())
{
progress.close();
QMessageBox::critical(nullptr,
QCoreApplication::translate("Launcher", "Security Check Failed"),
QCoreApplication::translate("Launcher", "A possible system time rollback was detected. Startup has been blocked."));
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)
{
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>
<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>
<translation>线</translation>
</message>
@@ -343,110 +343,150 @@ Please enter a new License for %2:</source>
<translation></translation>
</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>
<translation>退</translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="268"/>
<location filename="../Launcher/main.cpp" line="284"/>
<source>Update Required</source>
<translation></translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="268"/>
<location filename="../Launcher/main.cpp" line="284"/>
<source>New Version Available</source>
<translation></translation>
</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>
<translation> %1 退</translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="272"/>
<location filename="../Launcher/main.cpp" line="288"/>
<source>Version %1 is available. Update now?</source>
<translation> %1</translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="273"/>
<location filename="../Launcher/main.cpp" line="289"/>
<source>
Target version: %1</source>
<translation>
%1</translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="284"/>
<location filename="../Launcher/main.cpp" line="348"/>
<location filename="../Launcher/main.cpp" line="300"/>
<location filename="../Launcher/main.cpp" line="364"/>
<source>Startup Failed</source>
<translation></translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="285"/>
<location filename="../Launcher/main.cpp" line="349"/>
<location filename="../Launcher/main.cpp" line="301"/>
<location filename="../Launcher/main.cpp" line="365"/>
<source>Cannot start the main application: %1</source>
<translation>%1</translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="294"/>
<location filename="../Launcher/main.cpp" line="310"/>
<source>Updater Startup Failed</source>
<translation></translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="295"/>
<location filename="../Launcher/main.cpp" line="311"/>
<source>Cannot start the updater: %1</source>
<translation>%1</translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="303"/>
<location filename="../Launcher/main.cpp" line="319"/>
<source>Caching signed version manifest...</source>
<translation>...</translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="310"/>
<location filename="../Launcher/main.cpp" line="326"/>
<source>Manifest Cache Failed</source>
<translation></translation>
</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>
<translation>%1</translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="319"/>
<location filename="../Launcher/main.cpp" line="335"/>
<source>Server Unavailable</source>
<translation></translation>
</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>
<translation>线</translation>
</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>
<translation>线</translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="335"/>
<location filename="../Launcher/main.cpp" line="351"/>
<source>Network Unavailable</source>
<translation></translation>
</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>
<translation>线</translation>
</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>
<translation>...</translation>
</message>
<message>
<location filename="../Launcher/main.cpp" line="342"/>
<location filename="../Launcher/main.cpp" line="358"/>
<source>Offline mode is active. Starting...</source>
<translation>线...</translation>
</message>
</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>
<name>Updater</name>
<message>