mirror of
https://github.com/AmintaCCCP/GithubStarsManager.git
synced 2025-11-24 18:32:51 +08:00
216 lines
7.6 KiB
HTML
216 lines
7.6 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>更新功能测试</title>
|
|
<style>
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
padding: 20px;
|
|
line-height: 1.6;
|
|
}
|
|
.version-info {
|
|
background: #f5f5f5;
|
|
padding: 15px;
|
|
border-radius: 8px;
|
|
margin: 10px 0;
|
|
}
|
|
.changelog {
|
|
list-style: none;
|
|
padding: 0;
|
|
}
|
|
.changelog li {
|
|
padding: 5px 0;
|
|
border-left: 3px solid #007AFF;
|
|
padding-left: 10px;
|
|
margin: 5px 0;
|
|
}
|
|
button {
|
|
background: #007AFF;
|
|
color: white;
|
|
border: none;
|
|
padding: 10px 20px;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
}
|
|
button:hover {
|
|
background: #0056CC;
|
|
}
|
|
button:disabled {
|
|
background: #ccc;
|
|
cursor: not-allowed;
|
|
}
|
|
.error {
|
|
color: #FF3B30;
|
|
background: #FFE5E5;
|
|
padding: 10px;
|
|
border-radius: 6px;
|
|
margin: 10px 0;
|
|
}
|
|
.success {
|
|
color: #34C759;
|
|
background: #E5F7E5;
|
|
padding: 10px;
|
|
border-radius: 6px;
|
|
margin: 10px 0;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<h1>GitHub Stars Manager - 更新功能测试</h1>
|
|
|
|
<div>
|
|
<h2>当前版本: v0.1.4</h2>
|
|
<button id="checkUpdate" onclick="checkForUpdates()">检查更新</button>
|
|
<div id="status"></div>
|
|
<div id="updateInfo"></div>
|
|
</div>
|
|
|
|
<script>
|
|
// 模拟UpdateService的功能
|
|
class UpdateService {
|
|
static REPO_URL = './versions/version-info.xml'; // 本地测试用
|
|
static CURRENT_VERSION = '0.1.3';
|
|
|
|
static async checkForUpdates() {
|
|
try {
|
|
const response = await fetch(this.REPO_URL);
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
const xmlText = await response.text();
|
|
const versions = this.parseVersionXML(xmlText);
|
|
|
|
if (versions.length === 0) {
|
|
return {
|
|
hasUpdate: false,
|
|
currentVersion: this.CURRENT_VERSION
|
|
};
|
|
}
|
|
|
|
const latestVersion = versions[versions.length - 1];
|
|
const hasUpdate = this.compareVersions(this.CURRENT_VERSION, latestVersion.number) < 0;
|
|
|
|
return {
|
|
hasUpdate,
|
|
currentVersion: this.CURRENT_VERSION,
|
|
latestVersion: hasUpdate ? latestVersion : undefined
|
|
};
|
|
} catch (error) {
|
|
console.error('检查更新失败:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
static parseVersionXML(xmlText) {
|
|
const parser = new DOMParser();
|
|
const xmlDoc = parser.parseFromString(xmlText, 'text/xml');
|
|
|
|
const parseError = xmlDoc.querySelector('parsererror');
|
|
if (parseError) {
|
|
throw new Error('XML解析失败');
|
|
}
|
|
|
|
const versions = [];
|
|
const versionNodes = xmlDoc.querySelectorAll('version');
|
|
|
|
versionNodes.forEach(versionNode => {
|
|
const number = versionNode.querySelector('number')?.textContent?.trim();
|
|
const releaseDate = versionNode.querySelector('releaseDate')?.textContent?.trim();
|
|
const downloadUrl = versionNode.querySelector('downloadUrl')?.textContent?.trim();
|
|
|
|
if (!number || !releaseDate || !downloadUrl) {
|
|
return;
|
|
}
|
|
|
|
const changelog = [];
|
|
const changelogItems = versionNode.querySelectorAll('changelog item');
|
|
changelogItems.forEach(item => {
|
|
const text = item.textContent?.trim();
|
|
if (text) {
|
|
changelog.push(text);
|
|
}
|
|
});
|
|
|
|
versions.push({
|
|
number,
|
|
releaseDate,
|
|
changelog,
|
|
downloadUrl
|
|
});
|
|
});
|
|
|
|
return versions;
|
|
}
|
|
|
|
static compareVersions(version1, version2) {
|
|
const v1Parts = version1.split('.').map(Number);
|
|
const v2Parts = version2.split('.').map(Number);
|
|
|
|
const maxLength = Math.max(v1Parts.length, v2Parts.length);
|
|
|
|
for (let i = 0; i < maxLength; i++) {
|
|
const v1Part = v1Parts[i] || 0;
|
|
const v2Part = v2Parts[i] || 0;
|
|
|
|
if (v1Part < v2Part) return -1;
|
|
if (v1Part > v2Part) return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
async function checkForUpdates() {
|
|
const button = document.getElementById('checkUpdate');
|
|
const status = document.getElementById('status');
|
|
const updateInfo = document.getElementById('updateInfo');
|
|
|
|
button.disabled = true;
|
|
button.textContent = '检查中...';
|
|
status.innerHTML = '';
|
|
updateInfo.innerHTML = '';
|
|
|
|
try {
|
|
const result = await UpdateService.checkForUpdates();
|
|
|
|
if (result.hasUpdate && result.latestVersion) {
|
|
status.innerHTML = '<div class="success">发现新版本!</div>';
|
|
|
|
const version = result.latestVersion;
|
|
updateInfo.innerHTML = `
|
|
<div class="version-info">
|
|
<h3>版本 ${version.number}</h3>
|
|
<p><strong>发布日期:</strong> ${version.releaseDate}</p>
|
|
<p><strong>更新内容:</strong></p>
|
|
<ul class="changelog">
|
|
${version.changelog.map(item => `<li>${item}</li>`).join('')}
|
|
</ul>
|
|
<button onclick="window.open('${version.downloadUrl}', '_blank')">
|
|
立即下载
|
|
</button>
|
|
</div>
|
|
`;
|
|
} else {
|
|
status.innerHTML = '<div class="success">当前已是最新版本!</div>';
|
|
}
|
|
} catch (error) {
|
|
status.innerHTML = `<div class="error">检查更新失败: ${error.message}</div>`;
|
|
} finally {
|
|
button.disabled = false;
|
|
button.textContent = '检查更新';
|
|
}
|
|
}
|
|
|
|
// 页面加载时自动检查一次更新
|
|
window.addEventListener('load', () => {
|
|
setTimeout(checkForUpdates, 1000);
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |