Skip to content

Commit

Permalink
feat(script): 添加题库缓存功能
Browse files Browse the repository at this point in the history
  • Loading branch information
enncy committed Apr 23, 2023
1 parent e3468f7 commit 38bde15
Show file tree
Hide file tree
Showing 3 changed files with 266 additions and 12 deletions.
218 changes: 215 additions & 3 deletions packages/scripts/src/projects/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,11 @@ export const CommonProject = Project.create({
answererWrappers: {
defaultValue: [] as AnswererWrapper[]
},

enableQuestionCaches: {
label: '题库缓存功能',
defaultValue: true,
attrs: { type: 'checkbox', title: '详情请前往 通用-其他应用-题库拓展查看。' }
},
answererWrappersButton: {
label: '题库配置',
defaultValue: '点击配置',
Expand Down Expand Up @@ -813,11 +817,219 @@ export const CommonProject = Project.create({
}
}),
apps: new Script({
name: '📱 应用中心',
name: '📱 其他应用',
url: [['', /.*/]],
namespace: 'common.apps',
methods() {
type QuestionCache = { title: string; answer: string; from: string; homepage: string };

const getQuestionCache = async (): Promise<QuestionCache[]> => {
return (await $store.getTab(TAB_APPS_QUESTION_CACHES_KEY)) || [];
};

return {
/**
* 添加题库缓存
*/
addQuestionCache: async (...questionCacheItems: QuestionCache[]) => {
const questionCaches: QuestionCache[] = (await $store.getTab(TAB_APPS_QUESTION_CACHES_KEY)) || [];
for (const item of questionCacheItems) {
// 去重
if (questionCaches.find((c) => c.title === item.title && c.answer === item.answer) === undefined) {
questionCaches.push(item);
}
}

// 限制数量
questionCaches.splice(200);
await $store.setTab(TAB_APPS_QUESTION_CACHES_KEY, questionCaches);
},
addQuestionCacheFromWorkResult(swr: SimplifyWorkResult[]) {
CommonProject.scripts.apps.methods.addQuestionCache(
...swr
.map((r) =>
r.searchInfos
.map((i) =>
i.results
.filter((res) => res[1])
.map((res) => ({
title: r.question,
answer: res[1],
from: i.name.replace(/【题库缓存】/g, ''),
homepage: i.homepage || ''
}))
.flat()
)
.flat()
)
.flat()
);
},
getQuestionCache: getQuestionCache,
/**
* 将题库缓存作为题库并进行题目搜索
* @param title 题目
* @param whenSearchEmpty 当搜索结果为空,或者题库缓存功能被关闭时执行的函数
*/
searchAnswer: async (
title: string,
whenSearchEmpty: () => SearchInformation[] | Promise<SearchInformation[]>
): Promise<SearchInformation[]> => {
let results: SearchInformation[] = [];
const caches = await getQuestionCache();
for (const cache of caches) {
if (cache.title === title) {
results = [
{
name: `【题库缓存】${cache.from}`,
homepage: cache.homepage,
results: [{ answer: cache.answer, question: cache.title }]
}
];
}
}
if (results.length === 0) {
results = await whenSearchEmpty();
}
return results;
},
/**
* 查看最新通知
*/
async showNotify() {
const notify = el('div', { className: 'markdown card', innerHTML: '加载中...' });

$modal('simple', {
content: el('div', [
el('div', { className: 'notes card' }, [
$creator.notes([
'此页面实时更新,大家遇到问题可以看看通知',
el('div', ['或者进入 ', gotoHome(), ' 里的交流群进行反馈。'])
])
]),
notify
])
});
const md = await request('https://cdn.ocsjs.com/articles/ocs/notify.md?t=' + Date.now(), {
type: 'GM_xmlhttpRequest',
responseType: 'text',
method: 'get'
});
notify.innerHTML = markdown(md);
},
/**
* 查看更新日志
*/
async showChangelog() {
const changelog = el('div', {
className: 'markdown card',
innerHTML: '加载中...',
style: { maxWidth: '600px' }
});
$modal('simple', {
width: 600,
content: el('div', [
el('div', { className: 'notes card' }, [
$creator.notes(['此页面实时更新,遇到问题可以查看最新版本是否修复。'])
]),
changelog
])
});
const md = await request('https://cdn.ocsjs.com/articles/ocs/changelog.md?t=' + Date.now(), {
type: 'GM_xmlhttpRequest',
responseType: 'text',
method: 'get'
});
changelog.innerHTML = markdown(md);
}
};
},
onrender({ panel }) {
// $modal();
const btnStyle: Partial<CSSStyleDeclaration> = {
padding: '6px 12px',
margin: '4px',
marginBottom: '8px',
boxShadow: '0px 0px 4px #bebebe',
borderRadius: '8px',
cursor: 'pointer'
};

const cachesBtn = el('div', { innerText: '💾 题库缓存', style: btnStyle }, (btn) => {
btn.onclick = async () => {
const questionCaches = await this.methods.getQuestionCache();

const list = questionCaches.map((c) =>
el(
'div',
{
className: 'question-cache',
style: {
margin: '8px',
border: '1px solid lightgray',
borderRadius: '4px',
padding: '8px'
}
},
[
el('div', { className: 'title' }, [
$creator.tooltip(
el(
'span',
{
title: `来自:${c.from || '未知题库'}\n主页:${c.homepage || '未知主页'}`,
style: { fontWeight: 'bold' }
},
c.title
)
)
]),
el('div', { className: 'answer', style: { marginTop: '6px' } }, c.answer)
]
)
);

$modal('simple', {
width: 800,
content: el('div', [
el('div', { className: 'notes card' }, [
$creator.notes([
'题库缓存是将题库的题目和答案保存在内存,在重复使用时可以直接从内存获取,不需要再次请求题库。',
'以下是当前存储的题库,默认存储200题,当前页面关闭后会自动清除。'
])
]),
el('div', { className: 'card' }, [
$creator.space([
el('span', ['当前缓存数量:' + questionCaches.length]),
$creator.button('清空题库缓存', {}, (btn) => {
btn.onclick = () => {
$store.setTab(TAB_APPS_QUESTION_CACHES_KEY, []);
list.forEach((el) => el.remove());
};
})
])
]),

el(
'div',
questionCaches.length === 0 ? [el('div', { style: { textAlign: 'center' } }, '暂无题库缓存')] : list
)
])
});
};
});

[cachesBtn].forEach((btn) => {
btn.onmouseover = () => {
btn.style.boxShadow = '0px 0px 4px #0099ff9c';
};
btn.onmouseout = () => {
btn.style.boxShadow = '0px 0px 4px #bebebe';
};
});

panel.body.replaceChildren(
el('div', [el('div', { className: 'separator', style: { padding: '4px 0px' } }, '题库拓展'), cachesBtn])
);
}
})
}
Expand Down
26 changes: 24 additions & 2 deletions packages/scripts/src/projects/cx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,13 @@ export function workOrExam(
// 处理作业和考试题目
const title = workOrExamQuestionTitleTransform(elements.title);
if (title) {
return defaultAnswerWrapperHandler(answererWrappers, { type, title, root: ctx.root });
return CommonProject.scripts.apps.methods.searchAnswer(title, () => {
return defaultAnswerWrapperHandler(answererWrappers, {
type,
title,
options: ctx.elements.options.map((o) => o.innerText).join('\n')
});
});
} else {
throw new Error('题目为空,请查看题目是否为空,或者忽略此题');
}
Expand Down Expand Up @@ -710,6 +716,11 @@ export function workOrExam(
},
/** 监听答题结果 */
onResolveUpdate(res) {
if (res.result?.finish) {
CommonProject.scripts.apps.methods.addQuestionCacheFromWorkResult(
simplifyWorkResult([res], workOrExamQuestionTitleTransform)
);
}
CommonProject.scripts.workResults.methods.updateWorkState(worker);
}
});
Expand Down Expand Up @@ -1411,7 +1422,13 @@ async function chapterTestTask(
answerer: (elements, type, ctx) => {
const title = chapterTestTaskQuestionTitleTransform(elements.title);
if (title) {
return defaultAnswerWrapperHandler(answererWrappers, { type, title, root: ctx.root });
return CommonProject.scripts.apps.methods.searchAnswer(title, () => {
return defaultAnswerWrapperHandler(answererWrappers, {
type,
title,
options: ctx.elements.options.map((o) => o.innerText).join('\n')
});
});
} else {
throw new Error('题目为空,请查看题目是否为空,或者忽略此题');
}
Expand Down Expand Up @@ -1529,6 +1546,11 @@ async function chapterTestTask(
}
},
onResolveUpdate(res) {
if (res.result?.finish) {
CommonProject.scripts.apps.methods.addQuestionCacheFromWorkResult(
simplifyWorkResult([res], chapterTestTaskQuestionTitleTransform)
);
}
CommonProject.scripts.workResults.methods.updateWorkState(worker);
},
async onElementSearched(elements) {
Expand Down
34 changes: 27 additions & 7 deletions packages/scripts/src/projects/zhs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -888,12 +888,20 @@ function gxkWorkOrExam(
resolvePeriod: 1,
thread: thread ?? 1,
/** 默认搜题方法构造器 */
answerer: (elements, type, ctx) =>
defaultAnswerWrapperHandler(answererWrappers, {
type,
title: titleTransform(elements.title),
root: ctx.root
}),
answerer: (elements, type, ctx) => {
const title = titleTransform(elements.title);
if (title) {
return CommonProject.scripts.apps.methods.searchAnswer(title, () => {
return defaultAnswerWrapperHandler(answererWrappers, {
type,
title,
options: ctx.elements.options.map((o) => o.innerText).join('\n')
});
});
} else {
throw new Error('题目为空,请查看题目是否为空,或者忽略此题');
}
},
work: {
/** 自定义处理器 */
handler(type, answer, option) {
Expand All @@ -914,6 +922,9 @@ function gxkWorkOrExam(
CommonProject.scripts.workResults.methods.setResults(simplifyWorkResult(res, titleTransform));
},
onResolveUpdate(res) {
if (res.result?.finish) {
CommonProject.scripts.apps.methods.addQuestionCacheFromWorkResult(simplifyWorkResult([res], titleTransform));
}
CommonProject.scripts.workResults.methods.updateWorkState(worker);
}
});
Expand Down Expand Up @@ -1026,7 +1037,13 @@ function xnkWork({ answererWrappers, period, thread }: CommonWorkOptions) {
answerer: (elements, type, ctx) => {
const title = titleTransform(elements.title);
if (title) {
return defaultAnswerWrapperHandler(answererWrappers, { type, title, root: ctx.root });
return CommonProject.scripts.apps.methods.searchAnswer(title, () => {
return defaultAnswerWrapperHandler(answererWrappers, {
type,
title,
options: ctx.elements.options.map((o) => o.innerText).join('\n')
});
});
} else {
throw new Error('题目为空,请查看题目是否为空,或者忽略此题');
}
Expand Down Expand Up @@ -1061,6 +1078,9 @@ function xnkWork({ answererWrappers, period, thread }: CommonWorkOptions) {
}
},
onResolveUpdate(res) {
if (res.result?.finish) {
CommonProject.scripts.apps.methods.addQuestionCacheFromWorkResult(simplifyWorkResult([res], titleTransform));
}
CommonProject.scripts.workResults.methods.updateWorkState({
totalQuestionCount,
requestIndex,
Expand Down

0 comments on commit 38bde15

Please sign in to comment.