feat: 评分标准 JSON 导入/导出
This commit is contained in:
@@ -283,6 +283,37 @@ export function setupIpc(win: BrowserWindow): void {
|
||||
return null
|
||||
})
|
||||
|
||||
ipcMain.handle('rubric:exportJson', async () => {
|
||||
const d = getDb()
|
||||
const rows: any[] = d.prepare('SELECT * FROM rubric ORDER BY sort_order').all()
|
||||
if (!rows.length) throw new Error('暂无评分标准可导出')
|
||||
const questions = rows.map(r => ({
|
||||
questionTitle: r.question_title,
|
||||
maxScore: r.max_score,
|
||||
referenceAnswer: r.reference_answer,
|
||||
rubric: r.rubric
|
||||
}))
|
||||
const result = await dialogBox.showSaveDialog({
|
||||
defaultPath: '评分标准.json',
|
||||
filters: [{ name: 'JSON', extensions: ['json'] }]
|
||||
})
|
||||
if (result.canceled || !result.filePath) return false
|
||||
fs.writeFileSync(result.filePath, JSON.stringify(questions, null, 2), 'utf-8')
|
||||
return true
|
||||
})
|
||||
|
||||
ipcMain.handle('rubric:importJson', async () => {
|
||||
const result = await dialogBox.showOpenDialog({
|
||||
properties: ['openFile'],
|
||||
filters: [{ name: 'JSON', extensions: ['json'] }]
|
||||
})
|
||||
if (result.canceled || result.filePaths.length === 0) return null
|
||||
const content = fs.readFileSync(result.filePaths[0], 'utf-8')
|
||||
const questions = JSON.parse(content)
|
||||
if (!Array.isArray(questions)) throw new Error('JSON 格式错误:应为数组')
|
||||
return { questions, currentIndex: 0 }
|
||||
})
|
||||
|
||||
// --- Grading data bridge (toolbar → result window) ---
|
||||
ipcMain.handle('grading:storeData', (_event, data: any) => {
|
||||
gradingPayload = data
|
||||
|
||||
@@ -50,7 +50,9 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
||||
|
||||
rubric: {
|
||||
storeData: (data: any) => ipcRenderer.invoke('rubric:storeData', data),
|
||||
getData: () => ipcRenderer.invoke('rubric:getData')
|
||||
getData: () => ipcRenderer.invoke('rubric:getData'),
|
||||
exportJson: () => ipcRenderer.invoke('rubric:exportJson'),
|
||||
importJson: () => ipcRenderer.invoke('rubric:importJson')
|
||||
},
|
||||
|
||||
template: {
|
||||
|
||||
@@ -34,8 +34,14 @@
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<el-button size="small" @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" size="small" @click="handleSave">应用</el-button>
|
||||
<div class="footer-left">
|
||||
<el-button size="small" @click="handleImport">导入</el-button>
|
||||
<el-button size="small" @click="handleExport">导出</el-button>
|
||||
</div>
|
||||
<div class="footer-right">
|
||||
<el-button size="small" @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" size="small" @click="handleSave">应用</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
@@ -96,12 +102,39 @@ async function handleSave() {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleExport() {
|
||||
try {
|
||||
await window.electronAPI?.rubric.exportJson()
|
||||
ElMessage.success('导出成功')
|
||||
} catch (err) {
|
||||
ElMessage.error('导出失败:' + (err as Error).message)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleImport() {
|
||||
try {
|
||||
const data = await window.electronAPI?.rubric.importJson()
|
||||
if (data?.questions?.length) {
|
||||
questions.value = JSON.parse(JSON.stringify(data.questions))
|
||||
activeIndex.value = 0
|
||||
ElMessage.success(`已导入 ${data.questions.length} 题`)
|
||||
}
|
||||
} catch (err) {
|
||||
ElMessage.error('导入失败:' + (err as Error).message)
|
||||
}
|
||||
}
|
||||
|
||||
function handleClose() {
|
||||
window.electronAPI?.dialog.close()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
:deep(.el-dialog__footer) {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.question-tabs {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -136,4 +169,12 @@ function handleClose() {
|
||||
max-height: 480px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.footer-left {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
.footer-right {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
</style>
|
||||
@@ -81,6 +81,8 @@ export interface ElectronAPI {
|
||||
rubric: {
|
||||
storeData: (data: any) => Promise<void>
|
||||
getData: () => Promise<any>
|
||||
exportJson: () => Promise<boolean>
|
||||
importJson: () => Promise<{ questions: QuestionItem[]; currentIndex: number } | null>
|
||||
}
|
||||
template: {
|
||||
list: () => Promise<unknown[]>
|
||||
|
||||
Reference in New Issue
Block a user