From df0b8172f2618597962a5dd0fe91e0927ea88a18 Mon Sep 17 00:00:00 2001 From: yujialong <479214531@qq.com> Date: Thu, 1 Aug 2024 10:37:24 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E8=81=94=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ueditor/index.vue | 12 - src/const/testPaper.js | 34 +++ src/pages/ques/detail/index.vue | 52 +++-- src/pages/ques/list/index.vue | 20 +- src/pages/quesBank/index.vue | 5 +- src/pages/testPaper/detail/index.vue | 280 +++++++++++++++++------- src/pages/testPaper/detail/manual.vue | 253 ++++++++++++++------- src/pages/testPaper/detail/template.vue | 2 +- src/pages/testPaper/list/index.vue | 173 ++++++++++----- src/pages/testPaperLibrary/index.vue | 7 +- src/styles/common.scss | 5 + 11 files changed, 578 insertions(+), 265 deletions(-) create mode 100644 src/const/testPaper.js diff --git a/src/components/ueditor/index.vue b/src/components/ueditor/index.vue index cbb8467..018859d 100644 --- a/src/components/ueditor/index.vue +++ b/src/components/ueditor/index.vue @@ -25,7 +25,6 @@ export default { }, watch: { value: function (val, oldVal) { - console.log("🚀 ~ val:", val, this.ready) if (val != null && this.ready) { // eslint-disable-next-line no-undef this.instance = UE.getEditor(this.randomId) @@ -48,17 +47,6 @@ export default { // eslint-disable-next-line no-undef this.instance = UE.getEditor(this.randomId) this.instance.addListener('ready', () => { - - // UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl; - // UE.Editor.prototype.getActionUrl = function (action) { - // console.log("🚀 ~ initEditor ~ action:", action) - // if (action == 'uploadimage' || action == 'uploadscrawl' || action == 'uploadimage') { - // return 'http://192.168.31.51:9000/nakadai/nakadai/oss/fileUpload'; - // } else { - // return this._bkGetActionUrl.call(this, action); - // } - // } - this.ready = true this.$emit('ready', this.instance) }) diff --git a/src/const/testPaper.js b/src/const/testPaper.js new file mode 100644 index 0000000..d4a89d7 --- /dev/null +++ b/src/const/testPaper.js @@ -0,0 +1,34 @@ +export default { + difficults: [ + { + id: 1, + name: '简单' + }, + { + id: 2, + name: '普通' + }, + { + id: 3, + name: '较难' + }, + { + id: 4, + name: '难' + }, + ], + paperTypes: [ + { + id: 0, + name: '练习' + }, + { + id: 1, + name: '考核' + }, + { + id: 2, + name: '竞赛' + }, + ], +} diff --git a/src/pages/ques/detail/index.vue b/src/pages/ques/detail/index.vue index 3bf186d..16c5ff0 100644 --- a/src/pages/ques/detail/index.vue +++ b/src/pages/ques/detail/index.vue @@ -92,12 +92,12 @@ - + - +
@@ -124,7 +124,7 @@ - + @@ -187,7 +187,7 @@ import Setting from '@/setting' import Util from '@/libs/util' import Ueditor from '@/components/ueditor' -import Upload from '@/components/upload'; +import Upload from '@/components/upload' import Oss from '@/components/upload/upload.js' import dayjs from 'dayjs' import _ from 'lodash' @@ -281,16 +281,16 @@ export default { this.originForm = _.cloneDeep(this.form) }, methods: { + // 初始化 init () { this.form = _.cloneDeep(this.originForm) - // 选项默认 - for (let i = 1; i < 5; i++) { - const opt = _.cloneDeep(this.originOpt) - opt.optionNumber = i - this.form.questionAnswerVersions.push(opt) - } - this.form.questionAnswerVersions[0].answerIsCorrect = 1 + this.handleSingleMultiple() + // 外面知识点树形选中的知识点默认选中到表单里(选的是知识点才需要默认选中,知识点分类不用) + const knowledgeCheck = this.$parent.$refs.typeTree.getCurrentNode() + if (knowledgeCheck && knowledgeCheck.type) this.form.knowledgePointIds = [knowledgeCheck.path.split('/').map(e => +e)] + + // 富文本重置 this.$refs.stem && this.$refs.stem.setText('') this.$refs.answerAnalysis && this.$refs.answerAnalysis.setText('') this.$refs.uploadInstructions && this.$refs.uploadInstructions.setText('') @@ -371,6 +371,18 @@ export default { } }) }, + // 单选多选初始化 + handleSingleMultiple () { + // 选项默认 + const opts = [] + for (let i = 1; i < 5; i++) { + const opt = _.cloneDeep(this.originOpt) + opt.optionNumber = i + opts.push(opt) + } + this.form.questionAnswerVersions = opts + this.form.questionAnswerVersions[0].answerIsCorrect = 1 + }, // 题型选择回调 questionTypeChange (val) { // 判断题 @@ -395,7 +407,12 @@ export default { const opt = _.cloneDeep(this.originOpt) opt.gradingStandard = 'manual' opt.referenceAnswer = '' + this.form.allowAttachment = 0 + this.form.stemAttachment = '' + this.form.uploadInstructions = '' this.form.questionAnswerVersions = [opt] + } else { + this.handleSingleMultiple() } }, // 题干富文本加载完毕回调 @@ -559,11 +576,11 @@ export default { } } catch (e) { // 有重复的 - setTimeout(() => { - this.repeatVisible = true - this.repeats = Util.removeTag(e) - this.submiting = false - }, 1500) + // setTimeout(() => { + this.repeatVisible = true + this.repeats = Util.removeTag(e) + this.submiting = false + // }, 1500) } } }) @@ -588,9 +605,6 @@ export default { \ No newline at end of file diff --git a/src/pages/testPaper/detail/manual.vue b/src/pages/testPaper/detail/manual.vue index 97079d3..2501cae 100644 --- a/src/pages/testPaper/detail/manual.vue +++ b/src/pages/testPaper/detail/manual.vue @@ -7,15 +7,15 @@
- +
@@ -28,32 +28,39 @@

单选题(共{{ ques.length }}道题)

- + 序号 题干
- + {{ i + 1 }} - 题干 + {{ item.stem }}
-

已选试题(共{{ ques.length }}道题)

+
+

已选试题(共{{ checkedLen }}道题)

+ 批量移除 +
- + 序号 题干
-
- - {{ i + 1 }} - 题干 +
+
+ + {{ i + 1 }} + {{ item.stem }} +
+
@@ -66,7 +73,7 @@ 取消 - 确定 + 确定
@@ -75,22 +82,33 @@ import Setting from '@/setting' import Util from '@/libs/util' import _ from 'lodash' +import QuesConst from '@/const/ques' export default { - props: ['visible'], + props: ['visible', 'questionType'], data () { return { - checked: false, quesVisible: false, quesBankKeyword: '', knowledgeKeyword: '', searchTimer: null, + key: 1, quesBanks: [], knowledges: [], - ques: [{}, {}], + quesAllCheck: false, + ques: [], + checkedAllCheck: false, + checked: [], + curCheckQues: [], submiting: false, }; }, + computed: { + // 外面已经添加的试题+当前弹框已经勾选的试题 + checkedLen () { + return this.curCheckQues.length + this.checked.length + } + }, watch: { 'quesBankKeyword': function (val) { clearTimeout(this.searchTimer) @@ -110,9 +128,22 @@ export default { }, methods: { init () { + // 清空所有状态和数据 + this.key++ + this.knowledges = [] + this.ques = [] + this.checked = [] + this.quesAllCheck = false + this.checkedAllCheck = false + this.quesBankKeyword = '' + this.knowledgeKeyword = '' + + const parent = this.$parent.curType + this.curCheckQues = parent.examQuestions + this.getQuesBank() }, - // 获取题库分类 + // 获取题库 async getQuesBank () { try { const { data } = await this.$post(this.api.getAllQuestionBankCategories, { @@ -136,6 +167,36 @@ export default { } } catch (e) { } }, + // 获取试题 + async getQues () { + let k = this.$refs.knowledge.getCurrentNode() // 选中的知识点 + // 选中了知识点才能查询试题 + if (k && k.type) { + let { questionType } = this + if (questionType) questionType = QuesConst.questionTypes.find(e => e.name === questionType).id + const { message } = await this.$post(this.api.listQuestion, { + pageNum: 1, + pageSize: 1000, + status: 1, + // questionBankId: this.$refs.quesBank.getCurrentKey(), + // knowledgePointIds: [k.id], + questionTypes: questionType ? [questionType] : [], + questionBankId: 26, + knowledgePointIds: [18], + }) + const data = message.records + const checked = this.curCheckQues + data.map(e => { + const el = document.createElement('div') + el.innerHTML = e.stem + e.stem = el.innerText + e.check = !!this.checked.find(n => n.questionId === e.questionId) + e.disabled = !!checked.find(n => n.questionVersionId === e.questionId) + }) + this.ques = data + console.log("🚀 ~ getQues ~ data:", data, checked) + } + }, // 题库勾选回调 quesBankCheck (data, checked) { // debugger @@ -152,6 +213,71 @@ export default { // 知识点勾选回调 knowledgeCheck () { + }, + // 题目全选回调 + quesAllCheckChange (val) { + this.ques.map(e => { + e.check = val + this.quesChange(val, e) + }) + }, + // 题目多选回调 + quesChange (val, item) { + const cur = this.checked.findIndex(e => e.questionId === item.questionId) + // 选中 + if (val) { + if (cur === -1) { + const e = _.cloneDeep(item) + e.check = false + this.checked.push(e) + } + } else { + // 取消选中 + cur >= 0 && this.checked.splice(cur, 1) + } + }, + // 已选试题全选回调 + checkedAllCheckChange (val) { + this.checked.map(e => e.check = val) + }, + // 批量移除已选试题 + async batchDelChecked (val) { + try { + const checked = this.checked.filter(e => e.check) + if (checked.length) { + await this.$confirm(`确认要删除吗?`, '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + closeOnClickModal: false, + }) + checked.map(e => { + const cur = this.ques.find(n => n.questionId === e.questionId) + if (cur) { + cur.check = false + } + }) + this.quesAllCheck = false + this.checkedAllCheck = false + this.checked = this.checked.filter(e => !e.check) + } else { + Util.warningMsg('请选择数据') + } + } catch (e) { } + }, + // 已选试题单个删除 + async delChecked (item) { + try { + // await this.$confirm(`确认要删除吗?`, '提示', { + // confirmButtonText: '确定', + // cancelButtonText: '取消', + // type: 'warning', + // closeOnClickModal: false, + // }) + const cur = this.ques.find(e => e.questionId === item.questionId) + if (cur) cur.check = false + this.checked.splice(this.checked.findIndex(e => e.questionId === item.questionId), 1) + } catch (e) { } }, // 新增试题 toAddQues () { @@ -160,78 +286,27 @@ export default { // 修改目标 toEditQues () { - }, - // 使用模板 - async useTemplate (row) { - const data = await this.getDetail(row.templateId) - this.$parent.form.paperOutline = data.paperOutline - this.closeDia() - }, - // 获取详情 - async getDetail (id) { - const res = await this.$get(this.api.templateDetails, { - id - }) - return res.template - }, - // 编辑 - async edit (row) { - this.detailVisible = true - const data = await this.getDetail(row.templateId) - this.form = data - }, - // 删除 - async del (row) { - try { - await this.$confirm(`确认要删除【${row.templateName}】吗?`, '提示', { - confirmButtonText: '确定', - cancelButtonText: '取消', - type: 'warning', - closeOnClickModal: false, - }) - await this.$post(this.api.deleteTemplate, { - ids: [row.templateId] - }) - Util.successMsg('删除成功') - this.getList() - } catch (e) { } }, // 提交 async submit () { if (this.submiting) return false - const { form } = this - if (!form.templateName) return Util.warningMsg('请输入模板名称') - let invalid = 0 - for (const e of form.paperOutline) { - if (!e.questionType) { - Util.warningMsg('请选择题型') - invalid = 1 - break - } - if (!e.questionNum) { - Util.warningMsg('请输入目标题数') - invalid = 1 - break - } - if (!e.targetScore) { - Util.warningMsg('请输入目标分值') - invalid = 1 - break - } - } - if (invalid) return false - this.submiting = true - form.createSource = 1 - form.questionNum = this.questionNum - form.totalScore = this.totalScore - form.outlineNum = form.paperOutline.length - form.questionType = [...new Set(form.paperOutline.map(e => e.questionType))].join('、') + const checked = _.cloneDeep(this.checked) + if (!checked.length) return Util.warningMsg('请选择试题') + + const { curType, curQuesIndex } = this.$parent + if (this.checkedLen > +curType.questionNum) return Util.warningMsg(`目标题数为${curType.questionNum},已选题数不得大于目标题数`) + try { - await this.$post(this.api.saveExamPaperTemplate, form) - Util.successMsg('保存成功') - this.detailVisible = false + checked.map((e, i) => { + this.$set(e, 'check', false) + this.$set(e, 'sort', i + 1) + this.$set(e, 'score', '') + this.$set(e, 'questionVersionId', e.questionId) + }) + // debugger + typeof curQuesIndex === 'number' ? curType.examQuestions.splice(curQuesIndex + 1, 0, ...checked) : curType.examQuestions.push(...checked) + this.quesVisible = false this.submiting = false - this.getList() } catch (e) { this.submiting = false } @@ -263,12 +338,13 @@ export default { } .total { - margin-bottom: 10px; font-size: 16px; color: #333; } .ques { + margin-top: 10px; + .line { display: flex; align-items: center; @@ -280,6 +356,15 @@ export default { margin: 0 12px; text-align: center; } + + .check-left { + display: inline-flex; + align-items: center; + } + + .action-icon { + font-size: 14px; + } } } diff --git a/src/pages/testPaper/detail/template.vue b/src/pages/testPaper/detail/template.vue index 9a0dc97..20f3c37 100644 --- a/src/pages/testPaper/detail/template.vue +++ b/src/pages/testPaper/detail/template.vue @@ -246,7 +246,7 @@ export default { async useTemplate (row) { const data = await this.getDetail(row.templateId) this.$parent.form.paperOutline = data.paperOutline - this.closeDia() + this.listVisible = false }, // 获取详情 async getDetail (id) { diff --git a/src/pages/testPaper/list/index.vue b/src/pages/testPaper/list/index.vue index 850cc2e..95f677b 100644 --- a/src/pages/testPaper/list/index.vue +++ b/src/pages/testPaper/list/index.vue @@ -21,8 +21,9 @@
- + {{ data.classificationName }} @@ -63,37 +64,38 @@
  • - - + +
  • - - + +
  • - - + +
  • - - - + +
  • - - + +
  • - +
  • @@ -105,7 +107,7 @@
    创建试卷 批量移除 - 批量删除 + 批量删除
@@ -114,30 +116,46 @@ @selection-change="handleSelectionChange" row-key="id" @sort-change="sortChange"> - - - - - - - - + + + + + + + + + + + + - - - - + + + + + + + + + + - - + @@ -169,21 +187,21 @@ import Util from '@/libs/util' import _ from 'lodash' import Breadcrumb from '@/components/breadcrumb' +import QuesConst from '@/const/ques' +import TestPaperConst from '@/const/testPaper' export default { components: { Breadcrumb }, data () { return { + questionTypes: QuesConst.questionTypes, + difficults: TestPaperConst.difficults, + paperTypes: TestPaperConst.paperTypes, typeId: this.$route.query.id, createSource: 1, loading: false, - keyword: '', types: [], isNotJoin: 1, typeVisible: false, // 员工组织架对话框 - typeForm: { - classificationId: '', - classificationName: '' - }, cascaderValue: [], cascaderProps: { checkStrictly: true, @@ -191,30 +209,42 @@ export default { value: "classificationId" }, - status: [], - form: { - name: '', - parentId: [] + typeForm: { + classificationId: '', + classificationName: '' }, typeRules: { classificationName: [ { required: true, message: '请输入试卷分类名称', trigger: 'blur' } ] }, - rules: { - name: [ - { required: true, message: '请输入试卷名称', trigger: 'blur' } - ], - }, + professionals: [], + status: [ + { + id: 0, + name: '启用' + }, + { + id: 1, + name: '禁用' + }, + { + id: 2, + name: '草稿' + }, + ], + particularYear: '', + questionType: [], filter: { - difficultOrder: '', - yearOrder: '', + difficult: [], + professionalId: [], + paperType: '', + status: '', updateTimeOrder: '', crateTimeOrder: '', + yearOrder: '', keyWord: '', - difficult: '', - particularYear: '', - keyWord: '', + difficultOrder: '', }, listLoading: false, list: [], @@ -233,10 +263,6 @@ export default { }; }, watch: { - keyword: function () { - clearTimeout(this.searchTimer) - this.searchTimer = setTimeout(this.getType, 500) - }, 'filter.keyWord': function () { clearTimeout(this.searchTimer) this.searchTimer = setTimeout(this.getList, 500) @@ -253,6 +279,7 @@ export default { }, ], this.getType() + this.getProfessional() }, methods: { // 获取分类 @@ -367,12 +394,24 @@ export default { this.cascaderValue = [] this.getType() }, + // 获取所属专业 + async getProfessional () { + try { + const res = await this.$post(this.api.queryProfessional, { + pageNum: 1, + pageSize: 1000, + }) + this.professionals = res.pageList.records + } catch (e) { } + }, // 列表 async getList () { try { this.listLoading = true const res = await this.$post(this.api.examPaperList, { ...this.filter, + particularYear: this.particularYear ? [this.particularYear] : [], + questionType: this.questionType.length ? this.questionType.join() : '', type: this.isNotJoin, pageNum: this.page, pageSize: this.pageSize, @@ -399,27 +438,39 @@ export default { }, // 排序回调 sortChange (column) { - if (column.prop === 'createTime') this.filter.timeOrderBy = column.order ? column.order === 'ascending' ? 'asc' : 'desc' : '' + if (column.prop === 'difficult') this.filter.difficultOrder = column.order ? column.order === 'ascending' ? 1 : 2 : '' + if (column.prop === 'particularYear') this.filter.yearOrder = column.order ? column.order === 'ascending' ? 1 : 2 : '' + if (column.prop === 'createTime') this.filter.crateTimeOrder = column.order ? column.order === 'ascending' ? 1 : 2 : '' + if (column.prop === 'updateTime') this.filter.updateTimeOrder = column.order ? column.order === 'ascending' ? 1 : 2 : '' this.getList() }, // 删除 async del (row) { try { - await this.$confirm(`

确认要删除【${row.name}】吗?

删除后,关联此试卷的试题将自动移除此试卷!

`, '提示', { + await this.$confirm(`确认要删除【${row.name}】吗?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', - closeOnClickModal: false, dangerouslyUseHTMLString: true, }) - await this.$post(this.api.knowledgeHierarchyDel, [row.id]) + await this.$post(this.api.paperDel, { + delete: false, + ids: [row.paperId] + }) Util.successMsg('删除成功') this.getList() } catch (e) { } }, + async switchOff (val, row) { + await this.$post(this.api.paperDisable, { + id: row.paperId, + isDisable: val, + }) + this.getList() + }, // 添加试卷 add () { - this.$router.push(`detail?libraryId=${this.typeId}`) + this.$router.push(`detail?libraryId=${this.typeId}&classificationId=${this.$refs.typeTree.getCurrentKey() || ''}`) }, // 编辑试卷 async edit (row) { @@ -437,14 +488,16 @@ export default { const list = this.multipleSelection if (list.length) { try { - await this.$confirm(`

确认要删除已选定的${list.length}个试卷吗?

删除后,关联这些试卷的试题将自动移除这些试卷!

`, '提示', { + await this.$confirm(`确定要删除已选定的${list.length}份试卷吗?`, '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', closeOnClickModal: false, - dangerouslyUseHTMLString: true, }) - await this.$post(this.api.knowledgeHierarchyDel, list.map(e => e.id)) + await this.$post(this.api.paperDel, { + delete: false, + ids: list.map(e => e.paperId) + }) Util.successMsg('删除成功') this.multipleSelection = [] this.$refs.table.clearSelection() diff --git a/src/pages/testPaperLibrary/index.vue b/src/pages/testPaperLibrary/index.vue index e31a169..ff3ecbf 100644 --- a/src/pages/testPaperLibrary/index.vue +++ b/src/pages/testPaperLibrary/index.vue @@ -26,6 +26,7 @@
筛选
+
  • @@ -101,10 +102,12 @@