feat: 历史记录增强+IPC响应式Proxy修复+水印异常处理
This commit is contained in:
+66
-16
@@ -43,8 +43,31 @@ function getDb() {
|
||||
ai_score REAL,
|
||||
teacher_score REAL,
|
||||
confidence REAL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
question_title TEXT DEFAULT '',
|
||||
max_score REAL DEFAULT 100,
|
||||
reference_answer TEXT DEFAULT '',
|
||||
rubric TEXT DEFAULT '',
|
||||
deductions TEXT DEFAULT '',
|
||||
comment TEXT DEFAULT '',
|
||||
result_json TEXT DEFAULT '',
|
||||
image_data TEXT DEFAULT ''
|
||||
)`).run()
|
||||
// migrate: add columns for existing DBs
|
||||
const migrateCols: { name: string; type: string }[] = [
|
||||
{ name: 'question_title', type: 'TEXT DEFAULT \'\'' },
|
||||
{ name: 'max_score', type: 'REAL DEFAULT 100' },
|
||||
{ name: 'reference_answer', type: 'TEXT DEFAULT \'\'' },
|
||||
{ name: 'rubric', type: 'TEXT DEFAULT \'\'' },
|
||||
{ name: 'deductions', type: 'TEXT DEFAULT \'\'' },
|
||||
{ name: 'comment', type: 'TEXT DEFAULT \'\'' },
|
||||
{ name: 'result_json', type: 'TEXT DEFAULT \'\'' },
|
||||
{ name: 'image_data', type: 'TEXT DEFAULT \'\'' },
|
||||
{ name: 'reference_answer_image', type: 'TEXT DEFAULT \'\'' }
|
||||
]
|
||||
for (const col of migrateCols) {
|
||||
try { db.prepare(`ALTER TABLE history ADD COLUMN ${col.name} ${col.type}`).run() } catch (_) {}
|
||||
}
|
||||
db.prepare(`CREATE TABLE IF NOT EXISTS exam (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT,
|
||||
@@ -180,6 +203,15 @@ export function setupIpc(win: BrowserWindow): void {
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.handle('history:getById', (_event, id: number) => {
|
||||
try {
|
||||
const record = getDb().prepare('SELECT * FROM history WHERE id = ?').get(id) as any
|
||||
return record || null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.handle('grading:submit', (_event, data: {
|
||||
questionId: number
|
||||
imagePath: string
|
||||
@@ -187,22 +219,40 @@ export function setupIpc(win: BrowserWindow): void {
|
||||
teacherScore: number
|
||||
confidence: number
|
||||
studentAnswer?: string
|
||||
questionTitle?: string
|
||||
maxScore?: number
|
||||
referenceAnswer?: string
|
||||
rubric?: string
|
||||
deductions?: string[]
|
||||
comment?: string
|
||||
resultJson?: string
|
||||
imageData?: string
|
||||
referenceAnswerImage?: string
|
||||
}) => {
|
||||
try {
|
||||
getDb().prepare(`INSERT INTO history (question_id, image_path, student_answer, ai_score, teacher_score, confidence)
|
||||
VALUES (?, ?, ?, ?, ?, ?)`).run(
|
||||
data.questionId || 0,
|
||||
data.imagePath || '',
|
||||
data.studentAnswer || '',
|
||||
data.aiScore,
|
||||
data.teacherScore,
|
||||
data.confidence
|
||||
)
|
||||
return true
|
||||
} catch (err) {
|
||||
log.error('grading:submit error:', err)
|
||||
return false
|
||||
}
|
||||
log.info('grading:submit called', JSON.stringify({ ...data, imageData: data.imageData ? `len=${data.imageData.length}` : 'empty', referenceAnswerImage: data.referenceAnswerImage ? `len=${data.referenceAnswerImage.length}` : 'empty' }))
|
||||
const deductionsStr = JSON.stringify(data.deductions || [])
|
||||
getDb().prepare(`INSERT INTO history
|
||||
(question_id, image_path, student_answer, ai_score, teacher_score, confidence,
|
||||
question_title, max_score, reference_answer, rubric, deductions, comment, result_json, image_data,
|
||||
reference_answer_image)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(
|
||||
data.questionId || 0,
|
||||
data.imagePath || '',
|
||||
data.studentAnswer || '',
|
||||
data.aiScore,
|
||||
data.teacherScore,
|
||||
data.confidence,
|
||||
data.questionTitle || '',
|
||||
data.maxScore ?? 100,
|
||||
data.referenceAnswer || '',
|
||||
data.rubric || '',
|
||||
deductionsStr,
|
||||
data.comment || '',
|
||||
data.resultJson || '',
|
||||
data.imageData || '',
|
||||
data.referenceAnswerImage || ''
|
||||
)
|
||||
return true
|
||||
})
|
||||
|
||||
ipcMain.handle('template:list', () => {
|
||||
|
||||
@@ -33,7 +33,8 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
||||
|
||||
history: {
|
||||
list: () => ipcRenderer.invoke('history:list'),
|
||||
delete: (id: number) => ipcRenderer.invoke('history:delete', id)
|
||||
delete: (id: number) => ipcRenderer.invoke('history:delete', id),
|
||||
getById: (id: number) => ipcRenderer.invoke('history:getById', id)
|
||||
},
|
||||
|
||||
grading: {
|
||||
|
||||
Reference in New Issue
Block a user