feat(release): bump version to 0.1.2

## 详细信息
- 升级项目版本号到 0.1.2
- 增强刷课稳定性(失败重试、心跳检测、状态自动纠正)
- 优化账号页与工作台紧凑布局,增加已学/未学区分与记录筛选
- 新增首次进入更新检查、更新日志弹窗与在线下载/回退 Release 跳转
This commit is contained in:
2026-04-02 22:33:04 +08:00
parent a061123e36
commit 58555c5043
12 changed files with 1569 additions and 413 deletions

View File

@@ -193,18 +193,32 @@ const sleep = (ms: number) => new Promise((res) => setTimeout(res, ms));
export const runStudyQueue = async (_payload: StudyRunnerPayload) => {
const stopFlag = _payload.isRunningStudy;
const stepSeconds = Math.max(1, Math.floor(_payload.intervalSeconds || 5));
const sleepMs = stepSeconds * 1000;
const maxRetryCount = 3;
const maxStudySubmitRetry = 3;
const studySubmitRetrySleepMs = 5000;
for (const item of _payload.items) {
const learnedTime = Math.max(0, Math.floor(item.currentTime || 0));
const rawTotalTime = Math.max(0, Math.floor(item.totalTime || 0));
const totalTime = Math.max(0, rawTotalTime - learnedTime);
let currentTime = 0;
let count = 0;
let study_id = 0;
let total = item.totalTime - item.currentTime;
let retryCount = 0;
while (currentTime <= total) {
if (totalTime <= 0) {
_payload.onLog?.(`跳过已完成节点: ${item.name}`, _payload.accountId);
continue;
}
while (currentTime <= totalTime) {
if (!stopFlag()) {
_payload.onLog?.("⛔ 已手动停止", _payload.accountId);
return;
}
const message = `[${item.name}]: ${currentTime}/${total}`;
const message = `[${item.name}]: ${currentTime}/${totalTime}`;
_payload.onLog?.(message, _payload.accountId);
try {
@@ -212,8 +226,69 @@ export const runStudyQueue = async (_payload: StudyRunnerPayload) => {
node_id: item.nodeId,
study_id: String(study_id),
study_time: String(currentTime),
status: count === 0 ? 1 : currentTime >= total ? 3 : 2,
status: count === 0 ? 1 : currentTime >= totalTime ? 3 : 2,
});
const submitMessage = String(resp.data.msg ?? "");
const isSubmitFailed =
submitMessage.includes("提交学时失败") || resp.data.status === false;
if (isSubmitFailed) {
let submitRetry = 0;
let fixedResp = resp;
while (submitRetry < maxStudySubmitRetry) {
submitRetry += 1;
_payload.onLog?.(
`⚠️ 提交学时失败,${submitRetry}/${maxStudySubmitRetry} 次重试后再提交: ${item.name}`,
_payload.accountId,
);
await sleep(studySubmitRetrySleepMs);
if (!stopFlag()) {
_payload.onLog?.("⛔ 已手动停止", _payload.accountId);
return;
}
fixedResp = await _payload.client.studyApi({
node_id: item.nodeId,
study_id: String(study_id),
study_time: String(currentTime),
status: count === 0 ? 1 : currentTime >= totalTime ? 3 : 2,
});
const nextMsg = String(fixedResp.data.msg ?? "");
const nextFailed =
nextMsg.includes("提交学时失败") || fixedResp.data.status === false;
if (!nextFailed) {
break;
}
}
const finalMsg = String(fixedResp.data.msg ?? "");
const stillFailed =
finalMsg.includes("提交学时失败") || fixedResp.data.status === false;
if (stillFailed) {
_payload.onLog?.(
`⛔ 提交学时连续重试 ${maxStudySubmitRetry} 次仍失败,停止刷课: ${item.name}`,
_payload.accountId,
);
_payload.setIsRunningStudy();
return;
}
study_id = fixedResp.data.studyId;
retryCount = 0;
if (currentTime === totalTime) {
break;
}
currentTime = Math.min(currentTime + stepSeconds, totalTime);
count++;
await sleep(sleepMs);
continue;
}
if (resp.data.state != 0) {
_payload.onLog?.(`⛔ 自动停止: ${resp.data.msg}`, _payload.accountId);
_payload.setIsRunningStudy();
@@ -221,17 +296,29 @@ export const runStudyQueue = async (_payload: StudyRunnerPayload) => {
}
study_id = resp.data.studyId;
retryCount = 0;
if (currentTime === total) break;
if (currentTime === totalTime) {
break;
}
currentTime = Math.min(currentTime + 5, total);
currentTime = Math.min(currentTime + stepSeconds, totalTime);
count++;
} catch (error) {
retryCount += 1;
const errorMessage = `请求失败: ${error instanceof Error ? error.message : String(error)}`;
_payload.onLog?.(errorMessage, _payload.accountId);
if (retryCount >= maxRetryCount) {
_payload.onLog?.(
`⚠️ 连续失败 ${maxRetryCount} 次,跳过节点: ${item.name}`,
_payload.accountId,
);
break;
}
}
await sleep(5000);
await sleep(sleepMs);
}
}
};