diff --git a/electron/main/ipc.ts b/electron/main/ipc.ts
index b72bcc7..654d0f1 100644
--- a/electron/main/ipc.ts
+++ b/electron/main/ipc.ts
@@ -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
diff --git a/electron/preload/preload.ts b/electron/preload/preload.ts
index 68a0db5..cb1e781 100644
--- a/electron/preload/preload.ts
+++ b/electron/preload/preload.ts
@@ -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: {
diff --git a/src/components/RubricEditor.vue b/src/components/RubricEditor.vue
index c44431a..004d494 100644
--- a/src/components/RubricEditor.vue
+++ b/src/components/RubricEditor.vue
@@ -34,8 +34,14 @@
- 取消
- 应用
+
+
@@ -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()
}
\ No newline at end of file
diff --git a/src/types/index.ts b/src/types/index.ts
index 93ad479..8aa3019 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -81,6 +81,8 @@ export interface ElectronAPI {
rubric: {
storeData: (data: any) => Promise
getData: () => Promise
+ exportJson: () => Promise
+ importJson: () => Promise<{ questions: QuestionItem[]; currentIndex: number } | null>
}
template: {
list: () => Promise