diff --git a/packages/core/src/components/cx/ExamSettingPanel.tsx b/packages/core/src/components/cx/ExamSettingPanel.tsx
index d438d8ec..82303bd9 100644
--- a/packages/core/src/components/cx/ExamSettingPanel.tsx
+++ b/packages/core/src/components/cx/ExamSettingPanel.tsx
@@ -31,9 +31,8 @@ export const ExamSettingPanel = defineComponent({
value={settings.period}
min="3"
step="1"
- onChange={(e: any) => {
- settings.period = e.target.valueAsNumber;
- }}
+ onChange={(e: any) => (settings.period = e.target.valueAsNumber)}
+ onInput={(e: any) => (settings.period = e.target.valueAsNumber)}
/>
@@ -45,9 +44,8 @@ export const ExamSettingPanel = defineComponent({
value={settings.timeout}
min="0"
step="1"
- onChange={(e: any) => {
- settings.timeout = e.target.valueAsNumber;
- }}
+ onChange={(e: any) => (settings.timeout = e.target.valueAsNumber)}
+ onInput={(e: any) => (settings.timeout = e.target.valueAsNumber)}
/>
@@ -60,11 +58,23 @@ export const ExamSettingPanel = defineComponent({
min="0"
max="2"
step="1"
- onChange={(e: any) => {
- settings.retry = e.target.valueAsNumber;
- }}
+ onChange={(e: any) => (settings.retry = e.target.valueAsNumber)}
+ onInput={(e: any) => (settings.retry = e.target.valueAsNumber)}
/>
+
+
+
+ (settings.waitForCheck = e.target.valueAsNumber)}
+ onInput={(e: any) => (settings.waitForCheck = e.target.valueAsNumber)}
+ />
+
+
diff --git a/packages/core/src/components/cx/StudySettingPanel.tsx b/packages/core/src/components/cx/StudySettingPanel.tsx
index 41cf12e5..4882b2c9 100644
--- a/packages/core/src/components/cx/StudySettingPanel.tsx
+++ b/packages/core/src/components/cx/StudySettingPanel.tsx
@@ -103,9 +103,8 @@ export const StudySettingPanel = defineComponent({
value={store.setting.cx.work.period}
min="3"
step="1"
- onChange={(e: any) => {
- store.setting.cx.work.period = e.target.valueAsNumber;
- }}
+ onChange={(e: any) => (store.setting.cx.work.period = e.target.valueAsNumber)}
+ onInput={(e: any) => (store.setting.cx.work.period = e.target.valueAsNumber)}
/>
@@ -117,9 +116,8 @@ export const StudySettingPanel = defineComponent({
value={store.setting.cx.work.timeout}
min="0"
step="1"
- onChange={(e: any) => {
- store.setting.cx.work.timeout = e.target.valueAsNumber;
- }}
+ onChange={(e: any) => (store.setting.cx.work.timeout = e.target.valueAsNumber)}
+ onInput={(e: any) => (store.setting.cx.work.timeout = e.target.valueAsNumber)}
/>
@@ -132,11 +130,25 @@ export const StudySettingPanel = defineComponent({
min="0"
max="2"
step="1"
- onChange={(e: any) => {
- store.setting.cx.work.retry = e.target.valueAsNumber;
- }}
+ onChange={(e: any) => (store.setting.cx.work.retry = e.target.valueAsNumber)}
+ onInput={(e: any) => (store.setting.cx.work.retry = e.target.valueAsNumber)}
/>
+
+
+
+
+ (store.setting.cx.work.waitForCheck = e.target.valueAsNumber)}
+ onInput={(e: any) => (store.setting.cx.work.waitForCheck = e.target.valueAsNumber)}
+ />
+
+
+
);
diff --git a/packages/core/src/components/cx/WorkSettingPanel.tsx b/packages/core/src/components/cx/WorkSettingPanel.tsx
index 16e30425..9323e497 100644
--- a/packages/core/src/components/cx/WorkSettingPanel.tsx
+++ b/packages/core/src/components/cx/WorkSettingPanel.tsx
@@ -23,9 +23,8 @@ export const WorkSettingPanel = defineComponent({
value={settings.period}
min="3"
step="1"
- onChange={(e: any) => {
- settings.period = e.target.valueAsNumber;
- }}
+ onChange={(e: any) => (settings.period = e.target.valueAsNumber)}
+ onInput={(e: any) => (settings.period = e.target.valueAsNumber)}
/>
@@ -37,9 +36,8 @@ export const WorkSettingPanel = defineComponent({
value={settings.timeout}
min="0"
step="1"
- onChange={(e: any) => {
- settings.timeout = e.target.valueAsNumber;
- }}
+ onChange={(e: any) => (settings.timeout = e.target.valueAsNumber)}
+ onInput={(e: any) => (settings.timeout = e.target.valueAsNumber)}
/>
@@ -52,11 +50,23 @@ export const WorkSettingPanel = defineComponent({
min="0"
max="2"
step="1"
- onChange={(e: any) => {
- settings.retry = e.target.valueAsNumber;
- }}
+ onChange={(e: any) => (settings.retry = e.target.valueAsNumber)}
+ onInput={(e: any) => (settings.retry = e.target.valueAsNumber)}
/>
+
+
+
+ (settings.waitForCheck = e.target.valueAsNumber)}
+ onInput={(e: any) => (settings.waitForCheck = e.target.valueAsNumber)}
+ />
+
+
diff --git a/packages/core/src/components/zhs/WorkSettingPanel.tsx b/packages/core/src/components/zhs/WorkSettingPanel.tsx
index d457420a..c9915465 100644
--- a/packages/core/src/components/zhs/WorkSettingPanel.tsx
+++ b/packages/core/src/components/zhs/WorkSettingPanel.tsx
@@ -28,6 +28,7 @@ export const WorkSettingPanel = defineComponent({
(settings.period = e.target.valueAsNumber)}
+ onInput={(e: any) => (settings.period = e.target.valueAsNumber)}
value={settings.period}
min="3"
step="1"
@@ -40,6 +41,7 @@ export const WorkSettingPanel = defineComponent({
(settings.timeout = e.target.valueAsNumber)}
+ onInput={(e: any) => (settings.timeout = e.target.valueAsNumber)}
value={settings.timeout}
min="0"
step="1"
@@ -52,6 +54,7 @@ export const WorkSettingPanel = defineComponent({
(settings.retry = e.target.valueAsNumber)}
+ onInput={(e: any) => (settings.retry = e.target.valueAsNumber)}
value={settings.retry}
min="0"
max="2"
diff --git a/packages/core/src/script/cx/study.ts b/packages/core/src/script/cx/study.ts
index 64516d1d..ba763768 100644
--- a/packages/core/src/script/cx/study.ts
+++ b/packages/core/src/script/cx/study.ts
@@ -221,157 +221,155 @@ async function chapterTestTask(setting: ScriptSettings['cx']['work'], frame: HTM
if (store.setting.cx.video.upload === 'close') {
logger('warn', '自动答题已被关闭!');
- return;
- }
-
- logger('info', '开始自动答题');
-
- if (store.setting.answererWrappers.length === 0) {
+ } else if (store.setting.answererWrappers.length === 0) {
logger('warn', '题库配置为空,请设置。');
- return;
- }
-
- // @ts-ignore
- if (!frame.contentWindow) {
+ // @ts-ignore
+ } else if (!frame.contentWindow) {
logger('warn', '元素不可访问');
- return;
- }
-
- // 等待文字识别
- await waitForRecognize();
-
- const { window: frameWindow } = frame.contentWindow;
-
- const { TiMu } = domSearchAll({ TiMu: '.TiMu' }, frameWindow.document);
- /** 清空答案 */
- store.workResults = [];
-
- /** 新建答题器 */
- const worker = new OCSWorker({
- root: TiMu,
- elements: {
- title: '.Zy_TItle .clearfix',
- /**
- * 兼容各种选项
- *
- * ul li .after 单选多选
- * ul li label:not(.after) 判断题
- * ul li textarea 填空题
- */
- options: 'ul li .after,ul li textarea,ul textarea,ul li label:not(.before)',
- type: 'input[id^="answertype"]'
- },
- /** 默认搜题方法构造器 */
- answerer: (elements, type) => {
- const title = StringUtils.nowrap(elements.title[0].innerText)
- .replace(/(\d+)?【.*?题】/, '')
- .replace(/(\d+.0分)/, '')
- .trim();
- if (title) {
- return defaultAnswerWrapperHandler(store.setting.answererWrappers, type, title);
- } else {
- throw new Error('题目为空,请查看题目是否为空,或者忽略此题');
- }
- },
- /** 处理cx作业判断题选项是图片的问题 */
- onElementSearched(elements) {
- const typeInput = elements.type[0] as HTMLInputElement;
- const type = parseInt(typeInput.value);
- if (type === 3) {
- elements.options.forEach((option) => {
- const ri = option.querySelector('.ri');
- const span = document.createElement('span');
- span.innerText = ri ? '√' : '×';
- option.appendChild(span);
- });
- }
- },
- work: {
- /**
- * cx 题目类型 :
- * 0 单选题
- * 1 多选题
- * 2 简答题
- * 3 判断题
- * 4 填空题
- */
- type({ elements }) {
+ } else {
+ logger('info', '开始自动答题');
+
+ // 等待文字识别
+ await waitForRecognize();
+
+ const { window: frameWindow } = frame.contentWindow;
+
+ const { TiMu } = domSearchAll({ TiMu: '.TiMu' }, frameWindow.document);
+ /** 清空答案 */
+ store.workResults = [];
+
+ /** 新建答题器 */
+ const worker = new OCSWorker({
+ root: TiMu,
+ elements: {
+ title: '.Zy_TItle .clearfix',
+ /**
+ * 兼容各种选项
+ *
+ * ul li .after 单选多选
+ * ul li label:not(.after) 判断题
+ * ul li textarea 填空题
+ */
+ options: 'ul li .after,ul li textarea,ul textarea,ul li label:not(.before)',
+ type: 'input[id^="answertype"]'
+ },
+ /** 默认搜题方法构造器 */
+ answerer: (elements, type) => {
+ const title = StringUtils.nowrap(elements.title[0].innerText)
+ .replace(/(\d+)?【.*?题】/, '')
+ .replace(/(\d+.0分)/, '')
+ .trim();
+ if (title) {
+ return defaultAnswerWrapperHandler(store.setting.answererWrappers, type, title);
+ } else {
+ throw new Error('题目为空,请查看题目是否为空,或者忽略此题');
+ }
+ },
+ /** 处理cx作业判断题选项是图片的问题 */
+ onElementSearched(elements) {
const typeInput = elements.type[0] as HTMLInputElement;
-
const type = parseInt(typeInput.value);
- return type === 0
- ? 'single'
- : type === 1
- ? 'multiple'
- : type === 2
- ? 'completion'
- : type === 3
- ? 'judgement'
- : elements.options[0].querySelector('textarea')
- ? 'completion'
- : undefined;
+ if (type === 3) {
+ elements.options.forEach((option) => {
+ const ri = option.querySelector('.ri');
+ const span = document.createElement('span');
+ span.innerText = ri ? '√' : '×';
+ option.appendChild(span);
+ });
+ }
},
- /** 自定义处理器 */
- handler(type, answer, option) {
- if (type === 'judgement' || type === 'single' || type === 'multiple') {
- if (!option.parentElement?.querySelector('input')?.checked) {
- // @ts-ignore
- option.parentElement?.querySelector('a,label')?.click();
- }
- } else if (type === 'completion' && answer.trim()) {
- const text = option.parentElement?.querySelector('textarea');
- const textareaFrame = option.parentElement?.querySelector('iframe');
- if (text) {
- text.value = answer;
- }
- if (textareaFrame?.contentDocument) {
- textareaFrame.contentDocument.body.innerHTML = answer;
+ work: {
+ /**
+ * cx 题目类型 :
+ * 0 单选题
+ * 1 多选题
+ * 2 简答题
+ * 3 判断题
+ * 4 填空题
+ */
+ type({ elements }) {
+ const typeInput = elements.type[0] as HTMLInputElement;
+
+ const type = parseInt(typeInput.value);
+ return type === 0
+ ? 'single'
+ : type === 1
+ ? 'multiple'
+ : type === 2
+ ? 'completion'
+ : type === 3
+ ? 'judgement'
+ : elements.options[0].querySelector('textarea')
+ ? 'completion'
+ : undefined;
+ },
+ /** 自定义处理器 */
+ handler(type, answer, option) {
+ if (type === 'judgement' || type === 'single' || type === 'multiple') {
+ if (!option.parentElement?.querySelector('input')?.checked) {
+ // @ts-ignore
+ option.parentElement?.querySelector('a,label')?.click();
+ }
+ } else if (type === 'completion' && answer.trim()) {
+ const text = option.parentElement?.querySelector('textarea');
+ const textareaFrame = option.parentElement?.querySelector('iframe');
+ if (text) {
+ text.value = answer;
+ }
+ if (textareaFrame?.contentDocument) {
+ textareaFrame.contentDocument.body.innerHTML = answer;
+ }
}
}
- }
- },
- onResult: (res) => {
- if (res.ctx) {
- store.workResults.push(res);
- }
- console.log(res);
- logger('info', '题目完成结果 : ', res.result?.finish ? '完成' : '未完成');
- },
-
- /** 其余配置 */
- period: (period || 3) * 1000,
- timeout: (timeout || 30) * 1000,
- retry,
- stopWhenError: false
- });
+ },
+ onResult: (res) => {
+ if (res.ctx) {
+ store.workResults.push(res);
+ }
+ console.log(res);
+ logger('info', '题目完成结果 : ', res.result?.finish ? '完成' : '未完成');
+ },
- const results = await worker.doWork();
+ /** 其余配置 */
+ period: (period || 3) * 1000,
+ timeout: (timeout || 30) * 1000,
+ retry,
+ stopWhenError: false
+ });
- logger('info', '做题完毕', results);
+ const results = await worker.doWork();
- // 处理提交
- await worker.uploadHandler({
- uploadRate: store.setting.cx.video.upload,
- results,
- async callback(finishedRate, uploadable) {
- logger('info', '完成率 : ', finishedRate, ' , ', uploadable ? '5秒后将自动提交' : ' 5秒后将自动保存');
+ logger('info', '做题完毕', results);
- await sleep(5000);
+ // 处理提交
+ await worker.uploadHandler({
+ uploadRate: store.setting.cx.video.upload,
+ results,
+ async callback(finishedRate, uploadable) {
+ logger('info', '完成率 : ', finishedRate, ' , ', uploadable ? '5秒后将自动提交' : ' 5秒后将自动保存');
- if (uploadable) {
- // @ts-ignore 提交
- frameWindow.btnBlueSubmit();
+ await sleep(5000);
- await sleep(3000);
- /** 确定按钮 */
- // @ts-ignore 确定
- frameWindow.submitCheckTimes();
- } else {
- // @ts-ignore 禁止弹窗
- frameWindow.alert = () => { };
- // @ts-ignore 暂时保存
- frameWindow.noSubmit();
+ if (uploadable) {
+ // @ts-ignore 提交
+ frameWindow.btnBlueSubmit();
+
+ await sleep(3000);
+ /** 确定按钮 */
+ // @ts-ignore 确定
+ frameWindow.submitCheckTimes();
+ } else {
+ // @ts-ignore 禁止弹窗
+ frameWindow.alert = () => { };
+ // @ts-ignore 暂时保存
+ frameWindow.noSubmit();
+ }
}
- }
- });
+ });
+ }
+
+ if (setting.waitForCheck) {
+ logger('debug', `正在等待答题检查: 一共 ${setting.waitForCheck} 秒`);
+ await sleep(setting.waitForCheck * 1000);
+ }
}
diff --git a/packages/core/src/script/cx/work.ts b/packages/core/src/script/cx/work.ts
index c86e0fe9..0698d408 100644
--- a/packages/core/src/script/cx/work.ts
+++ b/packages/core/src/script/cx/work.ts
@@ -14,126 +14,127 @@ export async function workOrExam(
if (setting.upload === 'close') {
logger('warn', '自动答题已被关闭!');
- return;
- }
-
- if (store.setting.answererWrappers.length === 0) {
+ } else if (store.setting.answererWrappers.length === 0) {
logger('warn', '题库配置为空,请设置。');
- return;
- }
-
- /** 清空内容 */
- store.workResults = [];
-
- // 等待文字识别
- await waitForRecognize();
+ } else {
+ /** 清空内容 */
+ store.workResults = [];
- /** 新建答题器 */
- const worker = new OCSWorker({
- root: '.questionLi',
- elements: {
- title: 'h3',
- options: '.answerBg .answer_p, .textDIV, .eidtDiv',
- type: type === 'exam' ? 'input[name^="type"]' : 'input[id^="answertype"]'
- },
- /** 默认搜题方法构造器 */
- answerer: (elements, type) => {
- const title: string = StringUtils.nowrap(elements.title[0].innerText)
- .replace(/\d+\. \(.*?(题|分)\)/, '')
- .trim();
- if (title) {
- return defaultAnswerWrapperHandler(store.setting.answererWrappers, type, title);
- } else {
- throw new Error('题目为空,请查看题目是否为空,或者忽略此题');
- }
- },
+ // 等待文字识别
+ await waitForRecognize();
- work: {
- /**
- * cx 题目类型 :
- * 0 单选题
- * 1 多选题
- * 2 简答题
- * 3 判断题
- * 4 填空题
- */
- type({ elements }) {
- const typeInput = elements.type[0] as HTMLInputElement;
- const type = parseInt(typeInput.value);
- return type === 0
- ? 'single'
- : type === 1
- ? 'multiple'
- : type === 2
- ? 'completion'
- : type === 3
- ? 'judgement'
- : type === 4
- ? 'completion'
- : undefined;
+ /** 新建答题器 */
+ const worker = new OCSWorker({
+ root: '.questionLi',
+ elements: {
+ title: 'h3',
+ options: '.answerBg .answer_p, .textDIV, .eidtDiv',
+ type: type === 'exam' ? 'input[name^="type"]' : 'input[id^="answertype"]'
},
- /** 自定义处理器 */
- handler(type, answer, option) {
- if (type === 'judgement' || type === 'single' || type === 'multiple') {
- if (option.parentElement?.querySelector('.check_answer,.check_answer_dx') === null) {
- option.click();
- }
- } else if (type === 'completion' && answer.trim()) {
- const text = option.querySelector('textarea');
- const textareaFrame = option.querySelector('iframe');
- if (text) {
- text.value = answer;
- }
- if (textareaFrame?.contentDocument) {
- textareaFrame.contentDocument.body.innerHTML = answer;
+ /** 默认搜题方法构造器 */
+ answerer: (elements, type) => {
+ const title: string = StringUtils.nowrap(elements.title[0].innerText)
+ .replace(/\d+\. \(.*?(题|分)\)/, '')
+ .trim();
+ if (title) {
+ return defaultAnswerWrapperHandler(store.setting.answererWrappers, type, title);
+ } else {
+ throw new Error('题目为空,请查看题目是否为空,或者忽略此题');
+ }
+ },
+
+ work: {
+ /**
+ * cx 题目类型 :
+ * 0 单选题
+ * 1 多选题
+ * 2 简答题
+ * 3 判断题
+ * 4 填空题
+ */
+ type({ elements }) {
+ const typeInput = elements.type[0] as HTMLInputElement;
+ const type = parseInt(typeInput.value);
+ return type === 0
+ ? 'single'
+ : type === 1
+ ? 'multiple'
+ : type === 2
+ ? 'completion'
+ : type === 3
+ ? 'judgement'
+ : type === 4
+ ? 'completion'
+ : undefined;
+ },
+ /** 自定义处理器 */
+ handler(type, answer, option) {
+ if (type === 'judgement' || type === 'single' || type === 'multiple') {
+ if (option.parentElement?.querySelector('.check_answer,.check_answer_dx') === null) {
+ option.click();
+ }
+ } else if (type === 'completion' && answer.trim()) {
+ const text = option.querySelector('textarea');
+ const textareaFrame = option.querySelector('iframe');
+ if (text) {
+ text.value = answer;
+ }
+ if (textareaFrame?.contentDocument) {
+ textareaFrame.contentDocument.body.innerHTML = answer;
+ }
}
}
- }
- },
- onResult: (res) => {
- if (res.ctx) {
- store.workResults.push(res);
- }
- console.log(res);
- logger('info', '题目完成结果 : ', res.result?.finish ? '完成' : '未完成');
- },
+ },
+ onResult: (res) => {
+ if (res.ctx) {
+ store.workResults.push(res);
+ }
+ console.log(res);
+ logger('info', '题目完成结果 : ', res.result?.finish ? '完成' : '未完成');
+ },
- /** 其余配置 */
+ /** 其余配置 */
- period: (period || 3) * 1000,
- timeout: (timeout || 30) * 1000,
- retry,
- stopWhenError: false
- });
+ period: (period || 3) * 1000,
+ timeout: (timeout || 30) * 1000,
+ retry,
+ stopWhenError: false
+ });
- const results = await worker.doWork();
+ const results = await worker.doWork();
- logger('info', '做题完毕', results);
+ logger('info', '做题完毕', results);
- if (type === 'exam') {
- logger('info', '为了安全考虑,请自行检查后自行点击提交!');
- } else {
- // 处理提交
- await worker.uploadHandler({
- uploadRate: setting.upload,
- results,
- async callback(finishedRate, uploadable) {
- logger('info', '完成率 : ', finishedRate, ' , ', uploadable ? '5秒后将自动提交' : '5秒后将自动保存');
+ if (type === 'exam') {
+ logger('info', '为了安全考虑,请自行检查后自行点击提交!');
+ } else {
+ // 处理提交
+ await worker.uploadHandler({
+ uploadRate: setting.upload,
+ results,
+ async callback(finishedRate, uploadable) {
+ logger('info', '完成率 : ', finishedRate, ' , ', uploadable ? '5秒后将自动提交' : '5秒后将自动保存');
- await sleep(5000);
- if (uploadable) {
- // 提交
- domSearch({ submit: '.completeBtn' }).submit?.click();
- await sleep(2000);
- // @ts-ignore 确定
- // eslint-disable-next-line no-undef
- submitWork();
- } else {
- // @ts-ignore 暂时保存
- // eslint-disable-next-line no-undef
- saveWork();
+ await sleep(5000);
+ if (uploadable) {
+ // 提交
+ domSearch({ submit: '.completeBtn' }).submit?.click();
+ await sleep(2000);
+ // @ts-ignore 确定
+ // eslint-disable-next-line no-undef
+ submitWork();
+ } else {
+ // @ts-ignore 暂时保存
+ // eslint-disable-next-line no-undef
+ saveWork();
+ }
}
- }
- });
+ });
+ }
+ }
+
+ if (setting.waitForCheck) {
+ logger('debug', `正在等待答题检查: 一共 ${setting.waitForCheck} 秒`);
+ await sleep(setting.waitForCheck * 1000);
}
}
diff --git a/packages/core/src/scripts.ts b/packages/core/src/scripts.ts
index 4b273ef8..840fce72 100644
--- a/packages/core/src/scripts.ts
+++ b/packages/core/src/scripts.ts
@@ -11,9 +11,9 @@ export interface Setting {
restudy: boolean
}
work: Record &
- Pick, 'period' | 'timeout' | 'retry'> & { upload: string }
+ Pick, 'period' | 'timeout' | 'retry'> & { upload: string, waitForCheck: number }
exam: Record &
- Pick, 'period' | 'timeout' | 'retry'> & { upload: string }
+ Pick, 'period' | 'timeout' | 'retry'> & { upload: string, waitForCheck: number }
}
export type SupportPlatform = 'zhs' | 'cx'
@@ -45,14 +45,16 @@ export function defaultSetting(): Setting {
timeout: 30,
retry: 1,
stopWhenError: false,
- upload: 'save'
+ upload: 'save',
+ waitForCheck: 5
},
exam: {
period: 3,
timeout: 30,
retry: 1,
stopWhenError: false,
- upload: 'save'
+ upload: 'save',
+ waitForCheck: 5
}
};
}