Skip to content

Commit 1045ed4

Browse files
committed
feat: 更新下载链接至QQ群,添加智教下载源检查功能
1 parent 5c4bd90 commit 1045ed4

2 files changed

Lines changed: 107 additions & 20 deletions

File tree

index.html

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ <h1 class="typescale-display-medium" style="margin-left:24px;margin-right:24px;"
9494
</div>
9595

9696
<div class="hero-actions">
97-
<a href="https://discord.gg/ahj7eJWhEG" class="btn btn--filled">
98-
<i class="fab fa-discord"></i><span>Discord</span>
97+
<a href="https://qm.qq.com/q/qo32AclNh6" class="btn btn--filled">
98+
<i class="fab fa-qq"></i><span>QQ群</span>
9999
</a>
100100
<a href="#release-info" class="btn btn--tonal">
101101
<span class="material-symbols-outlined">download</span>
@@ -267,8 +267,6 @@ <h2 class="typescale-title-large">InkCanvasForClass CE</h2>
267267
<div class="footer-socials">
268268
<a href="https://github.com/InkCanvasForClass/community" aria-label="GitHub Repository"
269269
class="btn btn--icon"><i class="fab fa-github"></i></a>
270-
<a href="https://discord.gg/ahj7eJWhEG" aria-label="Discord Server" class="btn btn--icon"><i
271-
class="fab fa-discord"></i></a>
272270
<a href="https://qm.qq.com/q/qo32AclNh6" aria-label="QQ Group" class="btn btn--icon"><i
273271
class="fab fa-qq"></i></a>
274272
</div>

main.js

Lines changed: 105 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ document.addEventListener("DOMContentLoaded", function () {
5757
let currentIndex = 0;
5858
let showingBeta = false;
5959
let smartTeachAvailable = false;
60+
let smartTeachDownloadAvailable = false;
6061

6162
// --- API与镜像处理 ---
6263
function buildApiUrls(endpoint) {
@@ -74,11 +75,37 @@ document.addEventListener("DOMContentLoaded", function () {
7475

7576
// 提取版本号
7677
function extractVersionFromUrl(url) {
77-
const regex = /InkCanvasForClass\.CE\.(\d+\.\d+\.\d+\.\d+)\.zip/;
78+
// 匹配 .zip 或 .exe 文件中的版本号
79+
const regex = /InkCanvasForClass\.CE\.(\d+\.\d+\.\d+\.\d+)\.(zip|exe)/;
7880
const match = url.match(regex);
7981
return match ? match[1] : null;
8082
}
8183

84+
// 判断是否为测试版(基于发布日期分界)
85+
function isBetaRelease(release, isBetaRepo) {
86+
// 2025/12/1 作为分界日期
87+
const boundaryDate = new Date('2025-12-01T00:00:00Z');
88+
const releaseDate = new Date(release.published_at);
89+
90+
if (releaseDate < boundaryDate) {
91+
// 2025/12/1 之前:根据仓库判断
92+
return isBetaRepo;
93+
} else {
94+
// 2025/12/1 及之后:版本号 < 1.7.18.0 时根据仓库判断,>= 1.7.18.0 时全部为测试版
95+
const versionMatch = release.tag_name.match(/(\d+)\.(\d+)\.(\d+)\.(\d+)/);
96+
if (versionMatch) {
97+
const [, major, minor, patch, build] = versionMatch.map(Number);
98+
// 比较 1.7.18.0
99+
if (major < 1 || (major === 1 && minor < 7) || (major === 1 && minor === 7 && patch < 18)) {
100+
return isBetaRepo;
101+
} else {
102+
return true; // >= 1.7.18.0 全部为测试版
103+
}
104+
}
105+
return isBetaRepo;
106+
}
107+
}
108+
82109
// 测试智教下载源的可用性
83110
async function testSmartTeachAvailability() {
84111
try {
@@ -108,23 +135,53 @@ document.addEventListener("DOMContentLoaded", function () {
108135
}
109136

110137
function convertDownloadUrl(url, isBeta = false) {
111-
// 如果是 .exe 文件,强制走镜像源
138+
// .exe 文件强制走最快 GitHub 镜像源
112139
if (url.endsWith('.exe')) {
113140
if (fastestMirror && url.startsWith("https://github.com/")) {
114141
return url.replace("https://github.com/", `${fastestMirror}/https://github.com/`);
115142
}
116143
return url;
117144
}
118-
// 智教优先(非 .exe)
119-
if (smartTeachAvailable) {
120-
return buildSmartTeachUrl(url, isBeta);
121-
}
122-
if (fastestMirror && url.startsWith("https://github.com/")) {
123-
return url.replace("https://github.com/", `${fastestMirror}/https://github.com/`);
145+
146+
// .zip 文件优先尝试使用智教联盟,如果不可用则使用 GitHub 镜像
147+
if (url.endsWith('.zip')) {
148+
// 如果智教联盟可用,返回智教联盟URL供后续检查
149+
if (smartTeachAvailable) {
150+
return buildSmartTeachUrl(url, isBeta);
151+
}
152+
// 智教不可用,使用最快 GitHub 镜像
153+
if (fastestMirror && url.startsWith("https://github.com/")) {
154+
return url.replace("https://github.com/", `${fastestMirror}/https://github.com/`);
155+
}
124156
}
157+
125158
return url;
126159
}
127160

161+
// 检查智教联盟中文件是否存在
162+
async function checkSmartTeachFileExists(url, isBeta = false) {
163+
try {
164+
const fileName = url.split('/').pop();
165+
const basePath = isBeta ? COMMUNITY_BETA_PATH : COMMUNITY_PATH;
166+
const testUrl = `${SMART_TEACH_DOMAIN}${basePath}/${fileName}`;
167+
168+
const controller = new AbortController();
169+
const timeoutId = setTimeout(() => controller.abort(), 3000);
170+
171+
const response = await fetch(testUrl, {
172+
method: 'HEAD',
173+
signal: controller.signal,
174+
cache: 'no-store'
175+
});
176+
177+
clearTimeout(timeoutId);
178+
// 302 Found 或 403 Forbidden 都认为文件存在
179+
return response.status === 302 || response.status === 403 || response.status === 200;
180+
} catch (e) {
181+
return false;
182+
}
183+
}
184+
128185
async function fetchDataWithMirrors(urls, errorMessage = "获取数据失败") {
129186
for (const url of urls) {
130187
try {
@@ -186,13 +243,14 @@ document.addEventListener("DOMContentLoaded", function () {
186243
const r = currentReleases[idx];
187244
const assetsHtml = r.assets
188245
.map(a => {
189-
// 提取原始下载URL的版本号
190-
const version = extractVersionFromUrl(a.browser_download_url);
246+
// 提取原始下载URL的版本号,如果失败则使用 tag_name
247+
const version = extractVersionFromUrl(a.browser_download_url) || r.tag_name;
191248
const downloadUrl = convertDownloadUrl(a.browser_download_url, r._isBeta);
192249
return `
193250
<button data-download-url="${downloadUrl}"
194251
data-original-url="${a.browser_download_url}"
195252
data-version="${version}"
253+
data-is-beta="${r._isBeta}"
196254
class="btn btn--tonal download-btn">
197255
<span class="material-symbols-outlined">download</span>
198256
<span>${a.name} (${(a.size / 1024 / 1024).toFixed(2)} MB)</span>
@@ -309,16 +367,31 @@ document.addEventListener("DOMContentLoaded", function () {
309367

310368
// 下载按钮事件监听
311369
function handleDownloadBtnClick() {
312-
elements.releaseList.addEventListener('click', function(e) {
370+
elements.releaseList.addEventListener('click', async function(e) {
313371
const downloadBtn = e.target.closest('.download-btn');
314372
if (downloadBtn) {
315373
e.preventDefault();
316374
const downloadUrl = downloadBtn.getAttribute('data-download-url');
317375
const version = downloadBtn.getAttribute('data-version') || '最新版';
318376
const originalUrl = downloadBtn.getAttribute('data-original-url');
377+
const isBeta = downloadBtn.getAttribute('data-is-beta') === 'true';
378+
379+
let effectiveUrl = originalUrl;
380+
381+
// 对于 .zip 文件,如果智教可用,先检查文件是否存在
382+
if (originalUrl.endsWith('.zip') && smartTeachAvailable) {
383+
const exists = await checkSmartTeachFileExists(originalUrl, isBeta);
384+
if (exists) {
385+
effectiveUrl = downloadUrl;
386+
} else if (fastestMirror) {
387+
// 文件不存在,使用最快镜像
388+
effectiveUrl = originalUrl.replace("https://github.com/", `${fastestMirror}/https://github.com/`);
389+
}
390+
} else if (originalUrl.endsWith('.exe') && fastestMirror) {
391+
// .exe 文件使用最快镜像
392+
effectiveUrl = originalUrl.replace("https://github.com/", `${fastestMirror}/https://github.com/`);
393+
}
319394

320-
// 如果智教不可达,使用原URL
321-
const effectiveUrl = smartTeachAvailable ? downloadUrl : originalUrl;
322395
showDownloadModal(effectiveUrl, version);
323396
}
324397
});
@@ -383,10 +456,20 @@ document.addEventListener("DOMContentLoaded", function () {
383456
releasesBeta = await fetchDataWithMirrors(betaUrls, "Beta 版本获取失败") || [];
384457
}
385458

386-
const allReleases = [...releasesOfficial.map(r => ({...r, _isBeta: false})), ...releasesBeta.map(r => ({...r, _isBeta: true}))];
459+
// 为发行版设置 _isBeta 标志(基于发布日期分界)
460+
const allReleases = [
461+
...releasesOfficial.map(r => ({
462+
...r,
463+
_isBeta: isBetaRelease(r, false)
464+
})),
465+
...releasesBeta.map(r => ({
466+
...r,
467+
_isBeta: isBetaRelease(r, true)
468+
}))
469+
];
387470
const sortedReleases = allReleases.sort((a, b) => new Date(b.published_at) - new Date(a.published_at));
388471

389-
currentReleases = showingBeta ? sortedReleases : releasesOfficial;
472+
currentReleases = showingBeta ? sortedReleases : allReleases.filter(r => !r._isBeta);
390473

391474
currentIndex = 0;
392475
elements.releaseLoading.style.display = 'none';
@@ -429,7 +512,13 @@ document.addEventListener("DOMContentLoaded", function () {
429512
const releaseUrls = buildApiUrls(`${GITHUB_REPO_COMMUNITY}/releases`);
430513
releasesOfficial = await fetchDataWithMirrors(releaseUrls, "正式版本获取失败") || [];
431514

432-
currentReleases = releasesOfficial;
515+
// 为发行版设置 _isBeta 标志(基于发布日期分界)
516+
const processedReleases = releasesOfficial.map(r => ({
517+
...r,
518+
_isBeta: isBetaRelease(r, false)
519+
}));
520+
521+
currentReleases = processedReleases;
433522
currentIndex = 0;
434523

435524
elements.releaseLoading.style.display = 'none';

0 commit comments

Comments
 (0)