From 7a82c98d003e082dff3eb6321790dcfda5bbe213 Mon Sep 17 00:00:00 2001 From: chenqiang Date: Sun, 31 Aug 2025 10:31:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=90=8E=E5=8F=B0=E7=9A=84?= =?UTF-8?q?=E8=AF=95=E9=A2=98=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 1 - src/background/db/question.js | 14 + src/background/service/questionService.js | 29 + src/components/admin/QuestionAddForm.vue | 190 +++ .../admin/QuestionDescriptionEdit.vue | 75 ++ src/components/admin/Sider.vue | 10 - src/preload.js | 12 +- src/router/index.js | 6 + src/views/admin/QuestionManagementView.vue | 1128 +++++++++++++++++ 9 files changed, 1452 insertions(+), 13 deletions(-) create mode 100644 src/components/admin/QuestionAddForm.vue create mode 100644 src/components/admin/QuestionDescriptionEdit.vue create mode 100644 src/views/admin/QuestionManagementView.vue diff --git a/src/App.vue b/src/App.vue index 38aee27..18c0f02 100644 --- a/src/App.vue +++ b/src/App.vue @@ -9,7 +9,6 @@ font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - text-align: center; color: #2c3e50; } diff --git a/src/background/db/question.js b/src/background/db/question.js index b1fffa2..daf7e33 100644 --- a/src/background/db/question.js +++ b/src/background/db/question.js @@ -293,6 +293,19 @@ async function updateChoiceQuestion(id, choiceData) { }); } +/** + * 删除选择题问题 + * @param {number} id - 选择题ID + * @returns {Promise} 是否删除成功 + */ +async function deleteChoiceQuestion(id) { + const db = await getDbConnection(getSystemDbPath()); + return executeWithRetry(db, async () => { + const result = await db.runAsync('DELETE FROM question_choices WHERE id = ?', [id]); + return result.changes > 0; + }); +} + /** * 添加填空题问题 * @param {Object} fillBlankData - 填空题数据 @@ -415,6 +428,7 @@ module.exports = { updateQuestionDescription, addChoiceQuestion, updateChoiceQuestion, + deleteChoiceQuestion, addFillBlankQuestion, updateFillBlankQuestion, deleteFillBlankQuestion, diff --git a/src/background/service/questionService.js b/src/background/service/questionService.js index e049c75..1b567dd 100644 --- a/src/background/service/questionService.js +++ b/src/background/service/questionService.js @@ -8,6 +8,7 @@ const { updateQuestionDescription, addChoiceQuestion, updateChoiceQuestion, + deleteChoiceQuestion, // 添加这行 addFillBlankQuestion, updateFillBlankQuestion, deleteFillBlankQuestion, @@ -165,6 +166,23 @@ async function modifyChoiceQuestion(id, choiceData) { } } +/** + * 服务层:删除选择题问题 + * @param {number} id - 选择题ID + * @returns {Promise} 是否删除成功 + */ +async function removeChoiceQuestion(id) { + try { + const result = await deleteChoiceQuestion(id); + // 调用增加题库版本号的方法 + await increaseQuestionBankVersion(); + return result; + } catch (error) { + console.error('服务层: 删除选择题失败', error); + throw error; + } +} + /** * 服务层:添加填空题问题 * @param {Object} fillBlankData - 填空题数据 @@ -366,6 +384,16 @@ function initQuestionIpc(ipcMain) { } }); + // 添加删除选择题问题的IPC处理程序 + ipcMain.handle('question-delete-choice', async (event, id) => { + try { + return await removeChoiceQuestion(id); + } catch (error) { + console.error(`Failed to delete choice question ${id}:`, error); + throw error; + } + }); + // 根据题干ID查询填空题问题的IPC处理程序 ipcMain.handle('question-fetch-fill-blank-by-question-id', async (event, questionId) => { try { @@ -398,6 +426,7 @@ module.exports = { removeQuestion, createChoiceQuestion, modifyChoiceQuestion, + removeChoiceQuestion, // 添加这行 createFillBlankQuestion, modifyFillBlankQuestion, removeFillBlankQuestion, diff --git a/src/components/admin/QuestionAddForm.vue b/src/components/admin/QuestionAddForm.vue new file mode 100644 index 0000000..e4fe619 --- /dev/null +++ b/src/components/admin/QuestionAddForm.vue @@ -0,0 +1,190 @@ + + + + + \ No newline at end of file diff --git a/src/components/admin/QuestionDescriptionEdit.vue b/src/components/admin/QuestionDescriptionEdit.vue new file mode 100644 index 0000000..bd32308 --- /dev/null +++ b/src/components/admin/QuestionDescriptionEdit.vue @@ -0,0 +1,75 @@ + + + + + \ No newline at end of file diff --git a/src/components/admin/Sider.vue b/src/components/admin/Sider.vue index 0de97d4..343b6f0 100644 --- a/src/components/admin/Sider.vue +++ b/src/components/admin/Sider.vue @@ -140,16 +140,6 @@ export default { width: 100%; } -/* 设置el-menu-item的padding-left为0 */ -.el-menu-item { - padding-left: 0 !important; -} - -/* 对于折叠状态的菜单也应用相同的padding */ -.el-menu--collapse .el-menu-item { - padding-left: 0 !important; -} - /* 确保菜单中的图标和文字正确显示 */ .el-menu-item i { margin-right: 10px; diff --git a/src/preload.js b/src/preload.js index 238e968..b94ea36 100644 --- a/src/preload.js +++ b/src/preload.js @@ -36,14 +36,22 @@ contextBridge.exposeInMainWorld('electronAPI', { questionFetchAllWithRelations: () => ipcRenderer.invoke('question-fetch-all-with-relations'), questionUpdateDescription: (questionData) => ipcRenderer.invoke('question-update-description', questionData), questionAddChoice: (choiceData) => ipcRenderer.invoke('question-add-choice', choiceData), - questionUpdateChoice: (choiceData) => ipcRenderer.invoke('question-update-choice', choiceData), + // 修改questionUpdateChoice方法,使其接收两个参数并正确传递 + questionUpdateChoice: (id, choiceData) => ipcRenderer.invoke('question-update-choice', id, choiceData), questionDeleteChoice: (id) => ipcRenderer.invoke('question-delete-choice', id), + // 添加questionCreateChoice方法,调用主进程中已注册的'question-create-choice'通道 + questionCreateChoice: (choiceData) => ipcRenderer.invoke('question-create-choice', choiceData), questionAddFillBlank: (fillBlankData) => ipcRenderer.invoke('question-add-fill-blank', fillBlankData), - questionUpdateFillBlank: (fillBlankData) => ipcRenderer.invoke('question-update-fill-blank', fillBlankData), + // 添加新的questionCreateFillBlank方法,调用主进程中已注册的'question-create-fill-blank'通道 + questionCreateFillBlank: (fillBlankData) => ipcRenderer.invoke('question-create-fill-blank', fillBlankData), + // 修改questionUpdateFillBlank方法,使其接收两个参数并正确传递 + questionUpdateFillBlank: (id, fillBlankData) => ipcRenderer.invoke('question-update-fill-blank', id, fillBlankData), questionDeleteFillBlank: (id) => ipcRenderer.invoke('question-delete-fill-blank', id), questionGetQuestionWithChoices: (questionId) => ipcRenderer.invoke('question-get-question-with-choices', questionId), questionGetQuestionWithFillBlanks: (questionId) => ipcRenderer.invoke('question-get-question-with-fill-blanks', questionId), questionRemove: (questionId) => ipcRenderer.invoke('question-remove', questionId), + // 添加新的questionDelete方法,调用主进程中已注册的'question-delete'通道 + questionDelete: (questionId) => ipcRenderer.invoke('question-delete', questionId), questionGetStatistics: () => ipcRenderer.invoke('question-get-statistics'), questionGetQuestionById: (questionId) => ipcRenderer.invoke('question-get-question-by-id', questionId), diff --git a/src/router/index.js b/src/router/index.js index 31aaf82..8cb90e9 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -3,6 +3,7 @@ import VueRouter from 'vue-router' import WelcomeView from '../views/WelcomeView.vue' import AdminLayout from '../components/admin/AdminLayout.vue' import AdminHomeView from '../views/admin/AdminHomeView.vue' +import QuestionManagementView from '../views/admin/QuestionManagementView.vue' Vue.use(VueRouter) @@ -24,6 +25,11 @@ const routes = [ path: 'home', name: 'AdminHome', component: AdminHomeView + }, + { + path: 'question', + name: 'QuestionManagement', + component: QuestionManagementView } // 可以在这里添加更多子路由 ] diff --git a/src/views/admin/QuestionManagementView.vue b/src/views/admin/QuestionManagementView.vue new file mode 100644 index 0000000..b1d5f12 --- /dev/null +++ b/src/views/admin/QuestionManagementView.vue @@ -0,0 +1,1128 @@ + + + + + \ No newline at end of file