feat: add unified learning workflows and six-tab assistant

This commit is contained in:
薇星幻海
2026-10-18 01:11:33 +08:00
parent 20abb33740
commit eb9c610b9f
32 changed files with 23806 additions and 353 deletions
+8 -4
View File
@@ -7,7 +7,7 @@
const WAIT_LIMIT = 1200;
const CLICK_GAP = 150;
const COUNT_KEYS = ['selected', 'pending', 'missing', 'conflict', 'locked', 'failed', 'unsupported'];
const CONTEXT_KEYS = ['role', 'course', 'sourceUrl', 'routeKey', 'pageSignature', 'revision', 'exam', 'mode'];
const CONTEXT_KEYS = ['course', 'sourceUrl', 'routeKey', 'pageSignature', 'revision', 'exam', 'mode', 'topicKey'];
function normalize(value) {
// 仅中和排版空白和不可见分隔符;不折叠大小写、数字、单位或标点。
@@ -132,7 +132,6 @@
if (!context || context.ready !== true) return '等待答题页面就绪。';
if (context.local === true || root.location && root.location.protocol === 'file:') return '保存的静态网页可搜索和导出,不能记录自动选择。';
if (context.practice !== true && context.exam !== true) return '当前页面未识别为可作答的练习或考试,自动选择已停止。';
if (!context.role) return '请先选择主操、班长或副操。';
if (!context.root || !context.root.isConnected || context.root.ownerDocument !== doc) return '答题内容已切换,等待新页面。';
return '';
}
@@ -179,7 +178,7 @@
const context = options.getContext();
const reason = initialReason(context);
if (reason) return reason;
if (!sameContext(run.context, captureContext(context))) return '页面、岗位或题库已切换,已停止本轮自动选择。';
if (!sameContext(run.context, captureContext(context))) return '页面、主题或题库已切换,已停止本轮自动选择。';
return '';
}
@@ -339,6 +338,11 @@
async function execute(run, items) {
try {
for (const item of items) {
if (item !== items[0]) {
const configured = typeof options.getInterval === 'function' ? Number(options.getInterval()) : 0;
const gap = Number.isFinite(configured) ? Math.max(0, Math.min(120, configured)) * 1000 : 4000;
if (gap && !await wait(run, gap)) return progress();
}
if (!await processQuestion(run, item)) return progress();
if (run.cancelled || active !== run) return progress();
}
@@ -382,7 +386,7 @@
// 先写入 promise,再通知或执行,使同步 UI 回调中的 start 也不会并发运行。
run.promise = Promise.resolve().then(function () {
if (active !== run || run.cancelled) return progress();
notifyState('running', '正在选择当前岗位题库中的匹配答案。');
notifyState('running', '正在选择统一题库中的精确匹配答案。');
return execute(run, items);
});
return run.promise;