From 7616a664a0265bb6fbcffd11b24e70ae3f4a2845 Mon Sep 17 00:00:00 2001 From: NanGua-QWQ Date: Sun, 22 Feb 2026 15:42:34 +0800 Subject: [PATCH 1/2] FIX --- .../db/migrations/InitSchema2026011800000.ts | 2 +- src/main/services/AutoScoreService.ts | 38 ++++++++++--------- src/main/services/HttpServerService.ts | 2 +- .../src/components/AutoScoreManager.tsx | 2 +- src/renderer/src/components/Code.tsx | 2 - .../com.automatically/actions/index.ts | 2 +- .../src/components/com.automatically/index.ts | 6 +-- .../triggers/IntervalTimeTrigger.tsx | 4 +- 8 files changed, 27 insertions(+), 31 deletions(-) diff --git a/src/main/db/migrations/InitSchema2026011800000.ts b/src/main/db/migrations/InitSchema2026011800000.ts index 05cd578..f928626 100644 --- a/src/main/db/migrations/InitSchema2026011800000.ts +++ b/src/main/db/migrations/InitSchema2026011800000.ts @@ -81,7 +81,7 @@ export class InitSchema2026011800000 implements MigrationInterface { ('迟到','纪律',-1,1,CURRENT_TIMESTAMP), ('未交作业','作业情况',-2,1,CURRENT_TIMESTAMP) `) - + if (!(await queryRunner.hasTable('tags'))) { await queryRunner.query(` CREATE TABLE "tags" ( diff --git a/src/main/services/AutoScoreService.ts b/src/main/services/AutoScoreService.ts index c796668..5337f2c 100644 --- a/src/main/services/AutoScoreService.ts +++ b/src/main/services/AutoScoreService.ts @@ -357,7 +357,7 @@ export class AutoScoreService extends Service { // 使用AND/OR逻辑评估触发器 const matchedStudents = this.evaluateTriggersWithLogic(rule, studentsToScore) - + if (matchedStudents.length > 0) { for (const action of rule.actions || []) { await this.executeAction(action, matchedStudents, rule.name) @@ -387,7 +387,7 @@ export class AutoScoreService extends Service { for (let i = 0; i < rule.triggers.length; i++) { const trigger = rule.triggers[i] const logic = getTriggerLogic(trigger.event) - + if (!logic?.check) { continue } @@ -404,9 +404,9 @@ export class AutoScoreService extends Service { }, now: new Date() } - + const result = logic.check(context, trigger.value || '') - + if (!result.matchedStudents || result.matchedStudents.length === 0) { // 当前触发器没有匹配的学生 if (currentRelation === 'AND') { @@ -418,13 +418,13 @@ export class AutoScoreService extends Service { // 当前触发器有匹配的学生 if (currentRelation === 'AND') { // AND关系下,取交集 - currentGroup = currentGroup.filter(student => - result.matchedStudents!.some(matched => matched.id === student.id) + currentGroup = currentGroup.filter((student) => + result.matchedStudents!.some((matched) => matched.id === student.id) ) } else { // OR关系下,取并集 - const newStudents = result.matchedStudents.filter(matched => - !currentGroup.some(student => student.id === matched.id) + const newStudents = result.matchedStudents.filter( + (matched) => !currentGroup.some((student) => student.id === matched.id) ) currentGroup = [...currentGroup, ...newStudents] } @@ -433,14 +433,14 @@ export class AutoScoreService extends Service { // 处理下一个关系(如果存在) if (i < rule.triggers.length - 1) { const nextRelation = rule.triggers[i + 1].relation || 'AND' - + if (nextRelation !== currentRelation) { // 关系发生变化,处理当前组的结果 if (currentRelation === 'AND') { // AND组结束,如果当前组不为空,则合并到结果 if (currentGroup.length > 0) { - resultStudents = resultStudents.filter(student => - currentGroup.some(groupStudent => groupStudent.id === student.id) + resultStudents = resultStudents.filter((student) => + currentGroup.some((groupStudent) => groupStudent.id === student.id) ) } else { // AND组为空,整个规则不匹配 @@ -448,12 +448,13 @@ export class AutoScoreService extends Service { } } else { // OR组结束,合并当前组到结果 - const newStudents = currentGroup.filter(groupStudent => - !resultStudents.some(resultStudent => resultStudent.id === groupStudent.id) + const newStudents = currentGroup.filter( + (groupStudent) => + !resultStudents.some((resultStudent) => resultStudent.id === groupStudent.id) ) resultStudents = [...resultStudents, ...newStudents] } - + // 重置当前组为所有学生,开始新的关系组 currentGroup = [...initialStudents] currentRelation = nextRelation @@ -465,8 +466,8 @@ export class AutoScoreService extends Service { if (currentRelation === 'AND') { // AND组结束,如果当前组不为空,则合并到结果 if (currentGroup.length > 0) { - resultStudents = resultStudents.filter(student => - currentGroup.some(groupStudent => groupStudent.id === student.id) + resultStudents = resultStudents.filter((student) => + currentGroup.some((groupStudent) => groupStudent.id === student.id) ) } else { // AND组为空,整个规则不匹配 @@ -474,8 +475,9 @@ export class AutoScoreService extends Service { } } else { // OR组结束,合并当前组到结果 - const newStudents = currentGroup.filter(groupStudent => - !resultStudents.some(resultStudent => resultStudent.id === groupStudent.id) + const newStudents = currentGroup.filter( + (groupStudent) => + !resultStudents.some((resultStudent) => resultStudent.id === groupStudent.id) ) resultStudents = [...resultStudents, ...newStudents] } diff --git a/src/main/services/HttpServerService.ts b/src/main/services/HttpServerService.ts index 2fa3477..e745683 100644 --- a/src/main/services/HttpServerService.ts +++ b/src/main/services/HttpServerService.ts @@ -339,7 +339,7 @@ export class HttpServerService extends Service { // ww this.app.use - + // 404处理 this.app.use((_req: Request, res: Response) => { res.status(404).json({ diff --git a/src/renderer/src/components/AutoScoreManager.tsx b/src/renderer/src/components/AutoScoreManager.tsx index 0ce3904..7113720 100644 --- a/src/renderer/src/components/AutoScoreManager.tsx +++ b/src/renderer/src/components/AutoScoreManager.tsx @@ -569,7 +569,7 @@ export const AutoScoreManager: React.FC = () => { /> - + { if (editingRuleId !== null) { diff --git a/src/renderer/src/components/Code.tsx b/src/renderer/src/components/Code.tsx index b004348..555fea0 100644 --- a/src/renderer/src/components/Code.tsx +++ b/src/renderer/src/components/Code.tsx @@ -3,8 +3,6 @@ import { useEffect } from 'react' import Prism from 'prismjs' import { useTheme } from '../contexts/ThemeContext' -// 预先导入所有主题 -import 'prismjs/themes/prism-coy.min.css' import 'prismjs/themes/prism-okaidia.min.css' const Code = ({ code, language }) => { diff --git a/src/renderer/src/components/com.automatically/actions/index.ts b/src/renderer/src/components/com.automatically/actions/index.ts index 58a4c7b..c37133b 100644 --- a/src/renderer/src/components/com.automatically/actions/index.ts +++ b/src/renderer/src/components/com.automatically/actions/index.ts @@ -43,7 +43,7 @@ const actionDefinitions: ActionDefinition[] = [ description: sendNotificationDescription, component: SendNotificationAction, hasReason: sendNotificationHasReason - }, + } ] actionDefinitions.forEach((def) => actionRegistry.register(def)) diff --git a/src/renderer/src/components/com.automatically/index.ts b/src/renderer/src/components/com.automatically/index.ts index 3675db4..b1f962c 100644 --- a/src/renderer/src/components/com.automatically/index.ts +++ b/src/renderer/src/components/com.automatically/index.ts @@ -14,8 +14,4 @@ export { default as TriggerItemComponent } from './TriggerItem' export { default as ActionItemComponent } from './ActionItem' export { IntervalTimeTrigger, StudentTagTrigger, RandomTimeTrigger } from './triggers' -export { - AddScoreAction, - AddTagAction, - SendNotificationAction, -} from './actions' +export { AddScoreAction, AddTagAction, SendNotificationAction } from './actions' diff --git a/src/renderer/src/components/com.automatically/triggers/IntervalTimeTrigger.tsx b/src/renderer/src/components/com.automatically/triggers/IntervalTimeTrigger.tsx index 1bc62f6..e9c6e10 100644 --- a/src/renderer/src/components/com.automatically/triggers/IntervalTimeTrigger.tsx +++ b/src/renderer/src/components/com.automatically/triggers/IntervalTimeTrigger.tsx @@ -36,8 +36,8 @@ const IntervalTimeTrigger: React.FC = ({ value, onChange numValue === undefined || isNaN(numValue) ? undefined : unit === 'minutes' - ? numValue - : Math.max(1, Math.round(numValue / 1440)) + ? numValue + : Math.max(1, Math.round(numValue / 1440)) return ( From efa78f2bcebf2588c4057e12a5ad4314272e72b5 Mon Sep 17 00:00:00 2001 From: NanGua-QWQ Date: Sun, 22 Feb 2026 17:10:12 +0800 Subject: [PATCH 2/2] FIX lint error --- eslint.config.mjs | 4 +++- src/main/services/HttpServerService.ts | 7 +++---- .../src/components/TagEditorDialog.tsx | 19 ++++++++++--------- .../triggers/RandomTimeTrigger.tsx | 4 +++- src/shared/triggers/RandomTimeTrigger.ts | 5 ++++- 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 69fa8eb..e4fc897 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -31,7 +31,9 @@ export default defineConfig( 'react-refresh/only-export-components': 'off', 'react-hooks/exhaustive-deps': 'warn', 'react-hooks/set-state-in-effect': 'off', - '@typescript-eslint/no-require-imports': 'off' + '@typescript-eslint/no-require-imports': 'off', + // we use TypeScript types instead of PropTypes in React components + 'react/prop-types': 'off' } }, eslintConfigPrettier diff --git a/src/main/services/HttpServerService.ts b/src/main/services/HttpServerService.ts index e745683..a30090f 100644 --- a/src/main/services/HttpServerService.ts +++ b/src/main/services/HttpServerService.ts @@ -337,9 +337,7 @@ export class HttpServerService extends Service { } }) - // ww - this.app.use - + // stray expression removed // 404处理 this.app.use((_req: Request, res: Response) => { res.status(404).json({ @@ -349,7 +347,8 @@ export class HttpServerService extends Service { }) // 错误处理中间件 - this.app.use((error: Error, _: Request, res: Response, __: NextFunction) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + this.app.use((error: Error, _: Request, res: Response, _next: NextFunction) => { this.mainCtx.logger.error(`HTTP server error: ${error.message}`) res.status(500).json({ success: false, diff --git a/src/renderer/src/components/TagEditorDialog.tsx b/src/renderer/src/components/TagEditorDialog.tsx index 4a46f44..b15a821 100644 --- a/src/renderer/src/components/TagEditorDialog.tsx +++ b/src/renderer/src/components/TagEditorDialog.tsx @@ -29,15 +29,8 @@ export const TagEditorDialog: React.FC = ({ const themeMode = currentTheme?.mode || 'light' // 默认为 light - useEffect(() => { - if (visible) { - setSelectedTagIds(new Set(initialTagIds)) - setInputValue('') - fetchAllTags() - } - }, [visible, initialTagIds]) - - const fetchAllTags = async () => { + // fetchAllTags is declared as a function so it can be called from useEffect + async function fetchAllTags() { if (!(window as any).api) return try { const res = await (window as any).api.tagsGetAll() @@ -50,6 +43,14 @@ export const TagEditorDialog: React.FC = ({ } } + useEffect(() => { + if (visible) { + setSelectedTagIds(new Set(initialTagIds)) + setInputValue('') + fetchAllTags() + } + }, [visible, initialTagIds]) + const handleAddTag = async () => { const trimmed = inputValue.trim() if (!trimmed) return diff --git a/src/renderer/src/components/com.automatically/triggers/RandomTimeTrigger.tsx b/src/renderer/src/components/com.automatically/triggers/RandomTimeTrigger.tsx index 36d9801..4e0c03c 100644 --- a/src/renderer/src/components/com.automatically/triggers/RandomTimeTrigger.tsx +++ b/src/renderer/src/components/com.automatically/triggers/RandomTimeTrigger.tsx @@ -29,7 +29,9 @@ const RandomTimeTrigger: React.FC = ({ value, onChange }) const parsed = JSON.parse(value) config = { ...config, ...parsed } } - } catch {} + } catch (e) { + console.debug('RandomTimeTrigger parse error', e) + } const handleChange = (key: keyof RandomTimeConfig, v: any) => { const numV = typeof v === 'number' ? v : v ? Number(v) : undefined diff --git a/src/shared/triggers/RandomTimeTrigger.ts b/src/shared/triggers/RandomTimeTrigger.ts index 05e9db4..f7fce47 100644 --- a/src/shared/triggers/RandomTimeTrigger.ts +++ b/src/shared/triggers/RandomTimeTrigger.ts @@ -34,7 +34,10 @@ export const randomTimeTrigger: TriggerLogic = { const parsed = JSON.parse(value) config = { ...config, ...parsed } } - } catch {} + } catch (e) { + // swallow errors, use default config + console.debug('randomTimeTrigger calculateNextTime parse error', e) + } const minHour = config.minHour ?? 0 const maxHour = config.maxHour ?? 23